﻿/*
 * Copyright (c) 2011 http://DesignBased.NET 
 *
 * Permission is hereby granted, free of charge, to any person obtaining a copy of this software and associated documentation files (the "Software"), to deal in the 
 * Software  * without restriction, including without limitation the rights to use, copy, modify, merge, publish, distribute, sublicense, and/or sell copies of the 
 * Software, and to permit persons to whom the Software is furnished to do so, subject to the following conditions:
 * The above copyright notice and this permission notice shall be included in all copies or substantial portions of the Software.

 * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, FITNESS FOR
 * A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN 
 * ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. 
 * 
 */

using System;
using System.Collections.Generic;
using System.IO;
using System.Net;
using System.Text;
using Newtonsoft.Json;
using T163.Open.Api.Model;
using Newtonsoft.Json.Linq;

// oauth reference: http://oauthaccess.codeplex.com/

namespace T163.Open.Api
{
    /// <summary>
    /// oauth service
    /// </summary>
    public class OAuthService
    {
        #region fields/properties

        internal string realm = "tGoose";

        private OAuthRequest requestBase;

        internal Consumer Consumer
        {
            get;
            set;
        }

        internal RequestToken RequestToken
        {
            get;
            set;
        }

        internal AccessToken AccessToken
        {
            get;
            set;
        }

        internal string Verifier
        {
            get;
            set;
        }

        /// <summary>
        /// 当前用户
        /// </summary>
        public Users LogonUser
        {
            get;
            set;
        }

        #endregion

        #region 验证

        /// <summary>
        /// 创建一个OAuthService实例
        /// </summary>
        /// <param name="consumerKey">consumer key</param>
        /// <param name="consumerSecret">consumer secret</param>
        public OAuthService(string consumerKey, string consumerSecret)
        {
            this.Consumer = new Consumer(consumerKey, consumerSecret);
        }

        /// <summary>
        /// 获取Request Token
        /// 默认 Http 方法为 GET
        /// </summary>
        /// <param name="type">Http 方法类型</param>
        /// <returns></returns>
        public void GetRequestToken()
        {
            GetRequestToken(HttpMethodType.Get);
        }

        /// <summary>
        /// 获取Request Token
        /// </summary>
        /// <param name="type">Http 方法类型</param>
        /// <returns></returns>
        public void GetRequestToken(HttpMethodType type)
        {
            GetRequestToken(null, type);
        }

        /// <summary>
        /// 使用代理获取Request Token
        /// </summary>
        /// <param name="type">Http 方法类型</param>
        /// <param name="proxy">Http 代理</param>
        /// <returns></returns>
        public void GetRequestToken(WebProxy proxy, HttpMethodType type)
        {
            string authorizationHeader = OAuthUtility.GenerateAuthorizationHeader(
                realm,
                Urls.RequestToken,
                null,
                type,
                this.Consumer,
                null,
                null,
                new Parameter[] { });

            HttpWebRequest req = WebRequest.Create(Urls.RequestToken) as HttpWebRequest;
            req.Headers["Authorization"] = authorizationHeader;

            if (proxy != null)
            {
                req.Proxy = proxy;
            }

            OAuthResponse res = new OAuthResponse(req.GetResponse() as HttpWebResponse);

            List<Parameter> parameters = res.ResponseText.ParseParameters();

            RequestToken requestToken = new RequestToken(
                parameters.Find(p => p.Key == "oauth_token").Value,
                parameters.Find(p => p.Key == "oauth_token_secret").Value
                );

            this.RequestToken = requestToken;
        }

        /// <summary>
        /// 使用Request Token获取用户授权地址【WEB程序使用】
        /// </summary>
        /// <param name="callback">返回的地址</param>
        /// <returns>用户授权地址</returns>
        public string GetAuthorizationURL(string callback)
        {
            return string.Format("{0}?oauth_token={1}&oauth_callback={2}", Urls.Authenticate, this.RequestToken.Token, callback);
        }

        /// <summary>
        /// 使用Request Token获取用户授权地址【桌面程序使用】
        /// </summary>
        /// <returns>用户授权地址</returns>
        public string GetAuthorizationURL()
        {
            return string.Format("{0}?oauth_token={1}", Urls.Authorize, this.RequestToken.Token);
        }

        /// <summary>
        /// 获取Access Token
        /// 默认 Http 方法为 GET
        /// </summary>
        /// <param name="verifier">PIN码</param>
        /// <returns></returns>
        public void GetAccessToken(string verifier)
        {
            GetAccessToken(verifier, HttpMethodType.Get);
        }

        /// <summary>
        /// 获取Access Token
        /// </summary>
        /// <param name="verifier">PIN码</param>
        /// <param name="type">Http 方法类型</param>
        /// <returns></returns>
        public void GetAccessToken(string verifier, HttpMethodType type)
        {
            GetAccessToken(verifier, null, type);
        }

        /// <summary>
        /// 使用代理获取Access Token
        /// </summary>
        /// <param name="accessTokenUrl">地址</param>
        /// <param name="verifier">PIN码</param>
        /// <param name="type">Http 方法类型</param>
        /// <param name="proxy">Http 代理</param>
        /// <returns></returns>
        public void GetAccessToken(string verifier, WebProxy proxy, HttpMethodType type)
        {
            this.Verifier = verifier;

            string authorizationHeader = OAuthUtility.GenerateAuthorizationHeader(
                realm,
                Urls.AccessToken,
                string.Empty,
                type,
                this.Consumer,
                this.RequestToken,
                verifier,
                new Parameter[] { });

            HttpWebRequest req = WebRequest.Create(Urls.AccessToken) as HttpWebRequest;
            req.Headers["Authorization"] = authorizationHeader;

            if (proxy != null)
            {
                req.Proxy = proxy;
            }

            OAuthResponse res = new OAuthResponse(req.GetResponse() as HttpWebResponse);

            List<Parameter> parameters = res.ResponseText.ParseParameters();

            AccessToken accessToken = new AccessToken(
                parameters.Find(p => p.Key == "oauth_token").Value,
                parameters.Find(p => p.Key == "oauth_token_secret").Value
                );

            this.AccessToken = accessToken;
        }

        /// <summary>
        /// 验证用户是否登录成功并返回用户信息
        /// 【获取Access Token 后必须先调用这个方法获取用户信息后才能进行其他操作】
        /// </summary>
        /// <returns>用户或NULL</returns>
        public Users VerifyCredentials()
        {
            var verifyRequest = OAuthRequest.Create(this.Consumer, this.AccessToken).SetHttpMethod(HttpMethodType.Get).SetUrl(Urls.VerifyCredential).CommitRequest();
            var result = verifyRequest.GetResponse();

            if (result.IsSuccess && !string.IsNullOrEmpty(result.ResponseText))
            {
                requestBase = OAuthRequest.Create(this.Consumer, this.AccessToken).SetRealm(
                    this.realm).SetRetryCount(0).SetIgnoreStatusCodeCondition(i => i >= 500).SetHttpMethod(HttpMethodType.Get);

                LogonUser = JsonConvert.DeserializeObject<Users>(result.ResponseText);
                return LogonUser;
            }
            else
                return null;
        }

        #endregion

#if !NET20


        #region 微博列表

        /// <summary>
        /// 获取公共微博列表
        /// </summary>
        /// <param name="trimUser">可选参数，值为true时返回的user对象只包含id属性</param>
        /// <returns>微博列表</returns>
        public List<Statues> GetPublicTimeLine(bool trimUser = false)
        {
            var ptlRequest = requestBase.SetUrl(Urls.PublicTimeLine).AddParameter(new Parameter("trim_user", trimUser ? "true" : "false")).CommitRequest();
            var result = ptlRequest.GetResponse();

            if (result.IsSuccess && result.ResponseText != null)
            {
                return JsonConvert.DeserializeObject<List<Statues>>(result.ResponseText);
            }
            else
                return null;
        }

        /// <summary>
        /// 取得当前登录用户的微博列表
        /// </summary>
        /// <param name="sinceId">该参数需传cursor_id,返回此条索引之前发的微博列表,不包含此条</param>
        /// <param name="maxId">该参数需传cursor_id,返回此条索引之后发的微博列表，包含此条</param>
        /// <param name="trimUser">值为true时返回的user对象只包含id属性，该属性能在一定程度上减少返回的数据量</param>
        /// <param name="count">数量，默认为30条，最大为200条</param>
        /// <returns></returns>
        public List<Statues> GetHomeTimeLine(int count = 30, bool trimUser = true, string sinceId = "", string maxId = "")
        {
            if (count > 200)
                throw new ArgumentException("最大数量为200条", "count");

            var request = requestBase.SetUrl(Urls.HomeTimeLine).AddParameter(
                new Parameter[] {
                    new Parameter("count", count.ToString()),
                    new Parameter("trim_user", trimUser ? "true" : "false"),
                    new Parameter("since_id", sinceId),
                    new Parameter("max_id", maxId)
                }).CommitRequest();

            var result = request.GetResponse();

            if (result.IsSuccess && result.ResponseText != null)
            {
                return JsonConvert.DeserializeObject<List<Statues>>(result.ResponseText);
            }
            else
                return null;
        }

        /// <summary>
        /// 获取指定微博的转发列表
        /// </summary>
        /// <param name="id">必选参数，指定的微博id</param>
        /// <param name="count">选参数，数量，默认为30条，最大为200条</param>
        /// <param name="sinceId">可选参数，该参数需传微博id，返回此条索引之后发的微博列表，不包含此条</param>
        /// <param name="maxId">可选参数，该参数需传微博id，返回此条微博之前发的微博列表，包含此条</param>
        /// <param name="trimUser">可选参数，值为true时返回的user对象只包含id属性，该参数能在一定程度上减少返回的数据量</param>
        /// <returns></returns>
        public List<Statues> GetRetweets(string id, int count = 30, bool trimUser = true, string sinceId = "", string maxId = "")
        {
            var request = requestBase.SetHttpMethod(HttpMethodType.Get).SetUrl(string.Format(Urls.Retweets, id)).AddParameter(
                new Parameter[] {
                    new Parameter("count", count.ToString()),
                    new Parameter("since_id", sinceId),
                    new Parameter("max_id", maxId),
                    new Parameter("trim_user", trimUser ? "true" : "false")
                }).CommitRequest();

            var result = request.GetResponse();
            if (result.IsSuccess && result.ResponseText != null)
            {
                return JsonConvert.DeserializeObject<List<Statues>>(result.ResponseText);
            }
            else
                return null;
        }

        /// <summary>
        /// 获取@评论当前登录用户的微博列表
        /// </summary>
        /// <param name="sinceId">该参数需传cursor_id,返回此条索引之前发的微博列表,不包含此条</param>
        /// <param name="maxId">该参数需传cursor_id,返回此条索引之后发的微博列表，包含此条</param>
        /// <param name="trimUser">值为true时返回的user对象只包含id属性，该参数能在一定程度上减少返回的数据量</param>
        /// <param name="count">数量，默认为30条，最大为200条</param>
        /// <returns></returns>
        public List<Statues> GetMentions(int count = 30, bool trimUser = true, string sinceId = "", string maxId = "")
        {
            if (count > 200)
                throw new ArgumentException("最大数量为200条", "count");

            var request = requestBase.SetUrl(Urls.Mentions).AddParameter(
                new Parameter[] {
                    new Parameter("count", count.ToString()),
                    new Parameter("trim_user", trimUser ? "true" : "false"),
                    new Parameter("since_id", sinceId),
                    new Parameter("max_id", maxId)
                }).CommitRequest();

            var result = request.GetResponse();

            if (result.IsSuccess && result.ResponseText != null)
            {
                return JsonConvert.DeserializeObject<List<Statues>>(result.ResponseText);
            }
            else
                return null;
        }

        /// <summary>
        /// 获取指定用户的微博列表
        /// </summary>
        /// <param name="sinceId">可选参数，该参数需传cursor_id,返回此条索引之前发的微博列表,不包含此条</param>
        /// <param name="maxId">可选参数，该参数需传cursor_id,返回此条索引之后发的微博列表，包含此条</param>
        /// <param name="userId">可选参数. 用户ID，主要是用来区分用户ID跟微博昵称相同产生歧义的情况</param>
        /// <param name="name">可选参数，用户昵称</param>
        /// <param name="screenName">可选参数，可以传user_id或screen_name</param>
        /// <param name="trimUser">可选参数，值为true时返回的user对象只包含id属性，该属性能在一定程度上减少返回的数据量</param>
        /// <param name="count">可选参数，数量，默认为30条，最大为200条</param>
        /// <returns></returns>
        public List<Statues> GetUserTimeLine(string userId = "", string name = "", string screenName = "", bool trimUser = true, int count = 30, string sinceId = "", string maxId = "")
        {
            var request = requestBase.SetUrl(Urls.UserTimeLine).AddParameter(
               new Parameter[] {
                    new Parameter("name", name),
                    new Parameter("screen_name", screenName),
                    new Parameter("user_id", userId),
                    new Parameter("count", count.ToString()),
                    new Parameter("trim_user", trimUser ? "true" : "false"),
                    new Parameter("since_id", sinceId),
                    new Parameter("max_id", maxId)
                }).CommitRequest();

            var result = request.GetResponse();

            if (result.IsSuccess && result.ResponseText != null)
            {
                return JsonConvert.DeserializeObject<List<Statues>>(result.ResponseText);
            }
            else
                return null;
        }

        /// <summary>
        /// 获取当前登录用户所发微博被转发的列表
        /// </summary>
        /// <param name="sinceId">可选参数，该参数需传cursor_id,返回此条索引之前发的微博列表,不包含此条</param>
        /// <param name="count">可选参数，数量，默认为30条，最大为200条</param>
        /// <returns></returns>
        public List<Statues> GetRetweetsOfMe(int count = 30, string sinceId = "")
        {
            if (count > 200)
                throw new ArgumentException("最大数量为200条", "count");

            var request = requestBase.SetUrl(Urls.RetweetsOfMe).AddParameter(
                new Parameter[] {
                    new Parameter("count", count.ToString()),
                    new Parameter("since_id", sinceId)
                }).CommitRequest();

            var result = request.GetResponse();

            if (result.IsSuccess && result.ResponseText != null)
            {
                // reference: http://stackoverflow.com/questions/612689/a-generic-list-of-anonymous-class
                var retweets = new { created_at = "created_at", retweeted_status = new Statues() };
                var retweets1 = new { created_at = "created_at1", retweeted_status = new Statues() };

                var rtArray = new[] { retweets, retweets1 };

                var lst = JsonConvert.DeserializeAnonymousType(result.ResponseText, rtArray);

                List<Statues> stlst = new List<Statues>();
                foreach (var s in lst)
                {
                    stlst.Add(s.retweeted_status);
                }

                return stlst;
            }
            else
                return null;
        }

        /// <summary>
        /// 获取当前登录用户发出的评论列表
        /// </summary>
        /// <param name="sinceId">可选参数，该参数需传cursor_id,返回此条索引之后发的微博列表，包含此条</param>
        /// <param name="maxId">可选参数，该参数需传cursor_id,返回此条索引之后发的微博列表，包含此条</param>
        /// <param name="trimUser">可选参数，值为true时返回的user对象只包含id属性，该属性能在一定程度上减少返回的数据量。默认为true</param>
        /// <param name="count">选参数，数量，默认为30条，最大为200条</param>
        /// <returns></returns>
        public List<Statues> GetCommentsByMe(int count = 30, bool trimUser = true, string sinceId = "", string maxId = "")
        {
            if (count > 200)
                throw new ArgumentException("最大数量为200条", "count");

            var request = requestBase.SetUrl(Urls.CommentsByMe).AddParameter(
                new Parameter[] {
                    new Parameter("count", count.ToString()),
                    new Parameter("trim_user", trimUser ? "true" : "false"),
                    new Parameter("since_id", sinceId),
                    new Parameter("max_id", maxId)
                }).CommitRequest();

            var result = request.GetResponse();

            if (result.IsSuccess && result.ResponseText != null)
            {
                return JsonConvert.DeserializeObject<List<Statues>>(result.ResponseText);
            }
            else
                return null;
        }

        /// <summary>
        /// 获取当前登录用户收到的评论列表
        /// </summary>
        /// <param name="sinceId">可选参数，该参数需传cursor_id,返回此条索引之前发的微博列表,不包含此条</param>
        /// <param name="maxId">可选参数，该参数需传cursor_id,返回此条索引之后发的微博列表，包含此条</param>
        /// <param name="trimUser">可选参数，值为true时返回的user对象只包含id属性，该属性能在一定程度上减少返回的数据量。默认为true</param>
        /// <param name="count">可选参数，数量，默认为30条，最大为200条</param>
        /// <returns></returns>
        public List<Statues> GetCommentsToMe(int count = 30, bool trimUser = true, string sinceId = "", string maxId = "")
        {
            if (count > 200)
                throw new ArgumentException("最大数量为200条", "count");

            var request = requestBase.SetUrl(Urls.CommentsToMe).AddParameter(
                new Parameter[] {
                    new Parameter("count", count.ToString()),
                    new Parameter("trim_user", trimUser ? "true" : "false"),
                    new Parameter("since_id", sinceId),
                    new Parameter("max_id", maxId)
                }).CommitRequest();

            var result = request.GetResponse();

            if (result.IsSuccess && result.ResponseText != null)
            {
                return JsonConvert.DeserializeObject<List<Statues>>(result.ResponseText);
            }
            else
                return null;
        }

        #endregion

        #region 微博

        /// <summary>
        /// 发布一条微博。
        /// </summary>
        /// <param name="url">地址</param>
        /// <param name="statues">必选参数，微博内容，不得超过163个字符</param>
        /// <param name="lat">选参数，即纬度。范围在+90.0 到 -90.0，如果超出这个范围则忽略该值，必须与long参数一起使用，否则忽略该值。只有当用户的geo_enable为true时才有效</param>
        /// <param name="longGeo">可选参数,即经度。范围在+180.0到-180.0，如果超出这个范围则忽略该值，必须与lat参数一起使用，否则忽略该值。只有当用户的geo_enable为true时才有效</param>
        /// <param name="vid">可选参数,即 POI 的 ID，某一个具体的地点，比如天安门</param>
        /// <returns></returns>
        public Statues Update(Statues statues, double lat = 0, double longGeo = 0, string vid = "")
        {
            var request = requestBase.SetHttpMethod(HttpMethodType.Post).SetUrl(Urls.UpdateStatues).AddParameter(
                new Parameter[] { 
                    new Parameter("status", statues.Text), 
                    new Parameter("lat", lat.ToString()), 
                    new Parameter("long", longGeo.ToString()),
                    new Parameter("vid", vid)
                }).CommitRequest();

            var result = request.GetResponse();

            if (result.IsSuccess)
            {
                return JsonConvert.DeserializeObject<Statues>(result.ResponseText);
            }

            return null;
        }

        /// <summary>
        /// 评论一条微博
        /// </summary>
        /// <param name="id">必选参数，值为被评论微博的ID。如果回复某条评论，则此值为该评论的id。</param>
        /// <param name="statues">必选参数，评论内容</param>
        /// <param name="isRetweet">可选参数，是否转发 默认不转发 1为转发</param>
        /// <param name="isCommentToRoot">是否评论给原微博 默认不评论 1为评论</param>
        /// <returns></returns>
        public Statues Reply(string id, Statues statues, string isRetweet = "0", string isCommentToRoot = "0")
        {
            var request = requestBase.SetHttpMethod(HttpMethodType.Post).SetUrl(Urls.Reply).AddParameter(
                new Parameter[] {
                    new Parameter("id", id),
                    new Parameter("status", statues.Text),
                    new Parameter("is_retweet", isRetweet),
                    new Parameter("is_comment_to_root", isCommentToRoot)
                }).CommitRequest();

            var result = request.GetResponse();
            if (result.IsSuccess)
            {
                return JsonConvert.DeserializeObject<Statues>(result.ResponseText);
            }
            else
                return null;
        }

        /// <summary>
        /// 转发一条微博
        /// </summary>
        /// <param name="id">必选参数，值为被转发微博的ID</param>
        /// <param name="statues">可选参数，评论内容，默认为“转发微博。”</param>
        /// <param name="isComment">可选参数，是否评论 默认不评论 1为评论</param>
        /// <param name="isCommentToRoot">可选参数，是否评论给原微博 默认不评论 1为评论</param>
        /// <returns></returns>
        public Statues Retweet(string id, string isComment = "0", string isCommentToRoot = "0", Statues statues = null)
        {
            var request = requestBase.SetHttpMethod(HttpMethodType.Post).SetUrl(string.Format(Urls.Retweet, id)).AddParameter(
                new Parameter[] {
                    new Parameter("id", id),
                    new Parameter("status", statues == null ? "转发微博" : statues.Text),
                    new Parameter("is_comment", isComment),
                    new Parameter("is_comment_to_root", isCommentToRoot)
                }).CommitRequest();

            var result = request.GetResponse();
            if (result.IsSuccess)
            {
                return JsonConvert.DeserializeObject<Statues>(result.ResponseText);
            }
            else
                return null;
        }

        /// <summary>
        /// 获取单条微博信息
        /// </summary>
        /// <param name="id">必选参数，值为微博的ID</param>
        /// <returns></returns>
        public Statues Show(string id)
        {
            var request = requestBase.SetHttpMethod(HttpMethodType.Get).SetUrl(string.Format(Urls.Show, id)).AddParameter(
                new Parameter("id", id)).CommitRequest();

            var result = request.GetResponse();
            if (result.IsSuccess)
            {
                return JsonConvert.DeserializeObject<Statues>(result.ResponseText);
            }
            else
                return null;
        }

        /// <summary>
        /// 查看指定微博的所有评论
        /// </summary>
        /// <param name="id">必选参数，指定的微博id</param>
        /// <param name="sinceId">可选参数，该参数需传微博id，返回此条索引之后发的微博列表，不包含此条</param>
        /// <param name="maxId">可选参数，该参数需传微博id，返回此条微博之前发的微博列表，包含此条</param>
        /// <param name="count">可选参数，数量，默认为30条，最大为200条</param>
        /// <param name="trimUser">可选参数，值为true时返回的user对象只包含id属性，该参数能在一定程度上减少返回的数据量</param>
        /// <returns></returns>
        public List<Statues> Comments(string id, int count = 30, bool trimUser = true, string sinceId = "", string maxId = "")
        {
            var request = requestBase.SetHttpMethod(HttpMethodType.Get).SetUrl(string.Format(Urls.Comments, id)).AddParameter(
                new Parameter("since_id", sinceId),
                new Parameter("max_id", maxId),
                new Parameter("count", count.ToString()),
                new Parameter("trim_user", trimUser ? "true" : "false")).CommitRequest();

            var result = request.GetResponse();

            if (result.IsSuccess)
            {
                return JsonConvert.DeserializeObject<List<Statues>>(result.ResponseText);
            }
            else
                return null;
        }

        /// <summary>
        /// 删除指定的微博，也可以撤销已转发的微博
        /// </summary>
        /// <param name="id">必选参数，值为删除或撤销转发微博的ID</param>
        /// <returns></returns>
        public Statues Destroy(string id)
        {
            var request = requestBase.SetHttpMethod(HttpMethodType.Post).SetUrl(string.Format(Urls.Destroy, id)).CommitRequest();

            var result = request.GetResponse();

            if (result.IsSuccess)
            {
                return JsonConvert.DeserializeObject<Statues>(result.ResponseText);
            }
            else
                return null;
        }

        /// <summary>
        /// 获取一条微博被转发的用户信息
        /// </summary>
        /// <param name="id">必选参数，值为被转发微博的ID</param>
        /// <param name="count">可选参数，返回的用户数量，默认为100条，最大100条</param>
        /// <returns></returns>
        public List<Statues> GetRetweetedBy(string id, int count = 30)
        {
            var request = requestBase.SetHttpMethod(HttpMethodType.Get).SetUrl(string.Format(Urls.RetweetedBy, id)).AddParameter(
                new Parameter("count", count.ToString())).CommitRequest();

            var result = request.GetResponse();

            if (result.IsSuccess)
            {
                return JsonConvert.DeserializeObject<List<Statues>>(result.ResponseText);
            }
            else
                return null;
        }

        /// <summary>
        /// 上传图片文件并返回图片地址,将获得的图片地址通过发微博(statuses/update)接口附在微博正文里一同发出，则得到一个包含图片的微博
        /// </summary>
        /// <param name="filePath">图片路径，必选参数，支持jpg、png、bmp、gif这四种图片格式，上传图片大小在20M以内,此参数不参与Oauth签名。Oauth相关的验证参数请直接放在Header里</param>
        /// <returns></returns>
        private string UploadPic(string filePath)
        {
            return UploadPic(filePath, File.ReadAllBytes(filePath));
        }

        /// <summary>
        /// 上传图片文件并返回图片地址,将获得的图片地址通过发微博(statuses/update)接口附在微博正文里一同发出，则得到一个包含图片的微博
        /// </summary>
        /// <param name="fileName">图片名字，必选参数，支持jpg、png、bmp、gif这四种图片格式，上传图片大小在20M以内,此参数不参与Oauth签名。Oauth相关的验证参数请直接放在Header里</param>
        /// <param name="fileBytes">图片</param>
        /// <returns></returns>
        private string UploadPic(string fileName, byte[] fileBytes)
        {
            var boundary = Guid.NewGuid().ToString();
            var request = (HttpWebRequest)System.Net.WebRequest.Create(Urls.Upload);

            request.PreAuthenticate = true;
            request.AllowWriteStreamBuffering = true;
            request.Method = "POST";

            string oauthherad = OAuthUtility.GenerateAuthorizationHeader(realm, Urls.Upload, string.Empty, HttpMethodType.Post, this.Consumer, this.AccessToken, realm, new Parameter[] { });

            request.Headers.Add("Authorization", oauthherad);

            var header = string.Format("--{0}", boundary);
            var footer = string.Format("--{0}--", boundary);

            var contents = new StringBuilder();
            request.ContentType = string.Format("multipart/form-data; boundary={0}", boundary);

            contents.AppendLine(header);
            contents.AppendLine("Content-Type: text/plain; charset=US-ASCII");
            contents.AppendLine("Content-Transfer-Encoding: 8bit");
            contents.AppendLine();
            contents.AppendLine(this.Consumer.ConsumerKey);

            contents.AppendLine(header);
            string fileHeader = string.Format("Content-Disposition: form-data; name=\"{0}\"; filename=\"{1}\"", "pic", fileName);
            string fileData = System.Text.Encoding.GetEncoding("iso-8859-1").GetString(fileBytes);

            contents.AppendLine(fileHeader);
            contents.AppendLine("Content-Type: application/octet-stream; charset=UTF-8");
            contents.AppendLine("Content-Transfer-Encoding: binary");
            contents.AppendLine();
            contents.AppendLine(fileData);
            contents.AppendLine(footer);

            byte[] bytes = Encoding.GetEncoding("iso-8859-1").GetBytes(contents.ToString());
            request.ContentLength = bytes.Length;

            var requestStream = request.GetRequestStream();
            try
            {
                requestStream.Write(bytes, 0, bytes.Length);
            }
            catch (Exception ex)
            {
                throw new Exception("上传图片出错。", ex);
            }
            finally
            {
                requestStream.Close();
                requestStream = null;
            }

            StreamReader responseReader = null;
            string responseText = "";
            try
            {
                responseReader = new StreamReader(request.GetResponse().GetResponseStream());
                responseText = responseReader.ReadToEnd();

                JObject jobj = JObject.Parse(responseText);

                return jobj["upload_image_url"].Value<string>();
            }
            catch (Exception ex)
            {
                throw new Exception("上传图片出错。", ex);
            }
            finally
            {
                request.GetResponse().GetResponseStream().Close();
                responseReader.Close();
                responseReader = null;
            }
        }

        /// <summary>
        /// 发布图片微博
        /// </summary>
        /// <param name="filePath">图片路径，必选参数，支持jpg、png、bmp、gif这四种图片格式，上传图片大小在20M以内,此参数不参与Oauth签名。Oauth相关的验证参数请直接放在Header里</param>
        /// <param name="text">文字内容</param>
        /// <param name="lat">选参数，即纬度。范围在+90.0 到 -90.0，如果超出这个范围则忽略该值，必须与long参数一起使用，否则忽略该值。只有当用户的geo_enable为true时才有效</param>
        /// <param name="longGeo">可选参数,即经度。范围在+180.0到-180.0，如果超出这个范围则忽略该值，必须与lat参数一起使用，否则忽略该值。只有当用户的geo_enable为true时才有效</param>
        /// <param name="vid">可选参数,即 POI 的 ID，某一个具体的地点，比如天安门</param>
        /// <returns></returns>
        public Statues Upload(string filePath, string text = "", double lat = 0, double longGeo = 0, string vid = "")
        {
            string imageAddr = UploadPic(filePath);

            return Update(new Statues { Text = text + imageAddr }, lat, longGeo, vid);
        }

        /// <summary>
        /// 发布图片微博
        /// </summary>
        /// <param name="fileName">图片名字，必选参数，支持jpg、png、bmp、gif这四种图片格式，上传图片大小在20M以内,此参数不参与Oauth签名。Oauth相关的验证参数请直接放在Header里</param>
        /// <param name="fileBytes">图片</param>
        /// <param name="text">文字内容</param>
        /// <param name="lat">选参数，即纬度。范围在+90.0 到 -90.0，如果超出这个范围则忽略该值，必须与long参数一起使用，否则忽略该值。只有当用户的geo_enable为true时才有效</param>
        /// <param name="longGeo">可选参数,即经度。范围在+180.0到-180.0，如果超出这个范围则忽略该值，必须与lat参数一起使用，否则忽略该值。只有当用户的geo_enable为true时才有效</param>
        /// <param name="vid">可选参数,即 POI 的 ID，某一个具体的地点，比如天安门</param>
        /// <returns></returns>
        public Statues Upload(string fileName, byte[] fileBytes, string text = "", double lat = 0, double longGeo = 0, string vid = "")
        {
            string imageAddr = UploadPic(fileName, fileBytes);
            return Update(new Statues { Text = text + imageAddr }, lat, longGeo, vid);
        }

        #endregion

        #region 用户

        /// <summary>
        /// 获取指定用户信息
        /// </summary>
        /// <param name="id">可选参数，用户的个性网址或用户ID</param>
        /// <param name="name">可选参数，用户的昵称</param>
        /// <param name="user_id">可选参数，用户ID</param>
        /// <param name="screen_name">用户的个性网址</param>
        /// <returns></returns>
        public Users UserShow(string screen_name, string id = "", string name = "", string user_id = "")
        {
            var request = requestBase.SetHttpMethod(HttpMethodType.Get).SetUrl(Urls.UserShow).AddParameter(
                    new Parameter[] { 
                        new Parameter("id", id),
                        new Parameter("screen_name", screen_name),
                        new Parameter("name", name),
                        new Parameter("user_id", user_id)
                    }).CommitRequest();

            var result = request.GetResponse();

            if (result.IsSuccess)
            {
                return JsonConvert.DeserializeObject<Users>(result.ResponseText);
            }
            else
                return null;
        }

        /// <summary>
        /// 获取指定用户的关注用户列表
        /// </summary>
        /// <param name="userId">可选参数. 用户ID，主要是用来区分用户ID跟微博昵称相同产生歧义的情况</param>
        /// <param name="screenName">可选参数，该用户的个性网址，也可以传user_id</param>
        /// <param name="cursor">可选参数，分页参数，单页只能包含30个关注列表</param>
        /// <returns></returns>
        public List<Users> Friends(string userId = "", string screenName = "", int cursor = 1)
        {
            var request = requestBase.SetHttpMethod(HttpMethodType.Get).SetUrl(Urls.Friends).AddParameter(
                new Parameter("user_id", userId),
                new Parameter("screen_name", screenName),
                new Parameter("cursor", cursor.ToString())
                ).CommitRequest();

            var result = request.GetResponse();

            if (result.IsSuccess)
            {
                var fans = new { next_cursor = "1", users = new List<Users>(), previous_cursor = "-1" };
                return JsonConvert.DeserializeAnonymousType(result.ResponseText, fans).users;
            }
            else
                return null;
        }

        /// <summary>
        /// 获取指定被关注用户列表
        /// </summary>
        /// <param name="cursor">可选参数，分页参数，单页只能包含30个关注列表</param>
        /// <param name="userId">可选参数. 用户ID，主要是用来区分用户ID跟微博昵称相同产生歧义的情况</param>
        /// <param name="screenName">可选参数，该用户的个性网址，也可以传user_id</param>
        /// <returns></returns>
        public List<Users> Followers(string userId = "", string screenName = "", int cursor = 1)
        {
            var request = requestBase.SetHttpMethod(HttpMethodType.Get).SetUrl(Urls.Followers).AddParameter(
                new Parameter("user_id", userId),
                new Parameter("screen_name", screenName),
                new Parameter("cursor", cursor.ToString())
                ).CommitRequest();

            var result = request.GetResponse();

            if (result.IsSuccess)
            {
                var fans = new { next_cursor = "1", users = new List<Users>(), previous_cursor = "-1" };
                return JsonConvert.DeserializeAnonymousType(result.ResponseText, fans).users;
            }
            else
                return null;
        }

        /// <summary>
        /// 返回用户可能感兴趣的用户，随机返回指定数目的用户
        /// </summary>
        /// <param name="count">可选参数，指定随机返回的用户数目。默认为30个，最多返回30个</param>
        /// <param name="trimUser">可选参数，值为true时返回最基本的用户数据，使用此参数可以减少返回数据量，默认为false</param>
        /// <returns></returns>
        public List<Users> Suggestions(int count = 30, bool trimUser = false)
        {
            var request = requestBase.SetHttpMethod(HttpMethodType.Get).SetUrl(Urls.Suggestions).AddParameter(
                new Parameter("count", count.ToString()),
                new Parameter("trim_user", trimUser ? "true" : "false")).CommitRequest();

            var result = request.GetResponse();

            if (result.IsSuccess)
            {
                var slst = new { users = new List<Users>() };
                return JsonConvert.DeserializeAnonymousType(result.ResponseText, slst).users;
            }
            else
                return null;
        }

        /// <summary>
        /// 获取推荐的I达人的用户列表
        /// </summary>
        /// <param name="cursor">可选参数，分页参数</param>
        /// <param name="trimUser">可选参数，值为true时返回最基本的用户数据，使用此参数可以减少返回数据量，默认为false</param>
        /// <returns></returns>
        public List<Users> SuggestionsIFollowers(string cursor, bool trimUser = false)
        {
            var request =  requestBase.SetHttpMethod(HttpMethodType.Get).SetUrl(Urls.SuggestionsIFollowers).AddParameter(
                new Parameter("cursor", cursor),
                new Parameter("trim_user", trimUser ? "true" : "false")).CommitRequest();

            var result = request.GetResponse();
            if (result.IsSuccess)
            {
                var silst = new { users = new List<Users>() };
                return JsonConvert.DeserializeAnonymousType(result.ResponseText, silst).users;
            }
            else
                return null;
        }

        #endregion

        #region 关注

        /// <summary>
        /// 关注指定用户
        /// </summary>
        /// <param name="userId">可选参数. 用户ID，主要是用来区分用户ID跟微博昵称相同产生歧义的情况</param>
        /// <param name="screenName">可选参数，该用户的个性网址，也可以传user_id</param>
        /// <returns></returns>
        public Users FriendshipsCreate(string userId = "", string screenName = "")
        {
            var request = requestBase.SetHttpMethod(HttpMethodType.Post).SetUrl(Urls.FriendshipCreate).AddParameter(
                new Parameter("user_id", userId),
                new Parameter("screen_name", screenName)).CommitRequest();

            var result = request.GetResponse();
            if (result.IsSuccess)
            {
                return JsonConvert.DeserializeObject<Users>(result.ResponseText);
            }
            else
                return null;
        }

        /// <summary>
        /// 获取两个用户的相互关注关系
        /// </summary>
        /// <param name="sourceId">可选参数，指定用户的userId</param>
        /// <param name="sourceScreenName">可选参数，指定用户的个性网址</param>
        /// <param name="targetId">可选参数，指定用户的userId</param>
        /// <param name="targetScreenName">可选参数，目标用户的个性网址</param>
        /// <returns></returns>
        public Friendship FriendshipsShow(string targetId = "", string targetScreenName = "", string sourceId = "", string sourceScreenName = "")
        {
            if (string.IsNullOrWhiteSpace(targetId) && string.IsNullOrWhiteSpace(targetScreenName))
            {
                throw new ArgumentNullException("target_id 和 target_screen_name 不能同时为空。", "targetId/targetScreenName");
            }

            var request = requestBase.SetHttpMethod(HttpMethodType.Get).SetUrl(Urls.FriendshipShow).AddParameter(
                new Parameter[] {
                    new Parameter("source_id", sourceId),
                    new Parameter("source_screen_name", sourceScreenName),
                    new Parameter("target_id", targetId),
                    new Parameter("target_screen_name", targetScreenName)
                }).CommitRequest();

            var result = request.GetResponse();

            if (result.IsSuccess)
            {
                return JsonConvert.DeserializeObject<Friendship>(result.ResponseText);
            }
            else
                return null;
        }

        /// <summary>
        /// 取消关注指定用户
        /// </summary>
        /// <param name="userId">可选参数. 用户ID，主要是用来区分用户ID跟微博昵称相同产生歧义的情况</param>
        /// <param name="screenName">可选参数，该用户的个性网址，也可以传user_id</param>
        /// <returns></returns>
        public Users FriendshipsDestroy(string userId = "", string screenName = "")
        {
            var request = requestBase.SetHttpMethod(HttpMethodType.Post).SetUrl(Urls.FriendshipDestroy).AddParameter(
                new Parameter("user_id", userId),
                new Parameter("screen_name", screenName)).CommitRequest();

            var result = request.GetResponse();
            if (result.IsSuccess)
            {
                return JsonConvert.DeserializeObject<Users>(result.ResponseText);
            }
            else
                return null;
        }

        #endregion

        #region 热榜

        /// <summary>
        /// 获取当前的热门转发榜
        /// </summary>
        /// <param name="type">必选参数，排行榜类型,当前有4种:oneHour,sixHours,oneDay,oneWeek</param>
        /// <param name="size">可选参数，返回数量,不传则为默认值(当前为50),最多50</param>
        /// <returns></returns>
        public List<TopRetweets> TopRetweets(string type = "oneHour", int size = 50)
        {
            var request = requestBase.SetHttpMethod(HttpMethodType.Get).SetUrl(Urls.TopRetweets).AddParameter(
                new Parameter("type", type),
                new Parameter("size", size.ToString())).CommitRequest();

            var result = request.GetResponse();

            if (result.IsSuccess)
            {
                return JsonConvert.DeserializeObject<List<TopRetweets>>(result.ResponseText);
            }
            else
                return null;
        }

        #endregion

        #region 话题

        /// <summary>
        /// 推荐话题API，其效果与“我的首页”右侧的推荐话题一致
        /// </summary>
        /// <returns></returns>
        public List<Trend> TrendsRecommended()
        {
            var request = requestBase.SetHttpMethod(HttpMethodType.Get).SetUrl(Urls.TrendsRecommended).CommitRequest();

            var result = request.GetResponse();

            if (result.IsSuccess)
            {
                var Trends = new { trends = new List<Trend>() };

                return JsonConvert.DeserializeAnonymousType(result.ResponseText, Trends).trends;
            }
            else
                return null;
        }

        #endregion

        #region 私信

        /// <summary>
        /// 获取当前用户私信列表
        /// </summary>
        /// <param name="sinceId">可选参数，上一页最后一条私信的id</param>
        /// <param name="count">可选参数，获取私信的数量</param>
        /// <returns></returns>
        public List<DirectMessage> DirectMessages(int count = 20, string sinceId = "")
        {
            var request = requestBase.SetHttpMethod(HttpMethodType.Get).SetUrl(Urls.DirectMessages).AddParameter(
                new Parameter("count", count.ToString()), new Parameter("since_id", sinceId)).CommitRequest();

            var result = request.GetResponse();

            if (result.IsSuccess)
            {
                return JsonConvert.DeserializeObject<List<DirectMessage>>(result.ResponseText);
            }
            else
                return null;
        }

        /// <summary>
        /// 获取当前用户发送的私信列表
        /// </summary>
        /// <param name="sinceId">可选参数，上一页最后一条私信的id</param>
        /// <param name="count">可选参数，获取私信的数量</param>
        /// <returns></returns>
        public List<DirectMessage> DirectMessageSent(int count = 20, string sinceId = "")
        {
            var request = requestBase.SetHttpMethod(HttpMethodType.Get).SetUrl(Urls.DirectMessagesSent).AddParameter(
                new Parameter("count", count.ToString()), new Parameter("since_id", sinceId)).CommitRequest();

            var result = request.GetResponse();

            if (result.IsSuccess)
            {
                return JsonConvert.DeserializeObject<List<DirectMessage>>(result.ResponseText);
            }
            else
                return null;
        }

        /// <summary>
        /// 发送一条私信
        /// </summary>
        /// <param name="userName">必选参数，收信用户的昵称，即name</param>
        /// <param name="text">必选参数，私信内容</param>
        /// <returns></returns>
        public DirectMessage DirectMessageNew(string userName, string text)
        {
            var request = requestBase.SetHttpMethod(HttpMethodType.Post).SetUrl(Urls.DirectMessagesNew).AddParameter(
                new Parameter("user", userName), 
                new Parameter("text", text)).CommitRequest();

            var result = request.GetResponse();

            if (result.IsSuccess)
            {
                return JsonConvert.DeserializeObject<DirectMessage>(result.ResponseText);
            }
            else
                return null;
        }

        /// <summary>
        /// 删除一条私信
        /// </summary>
        /// <param name="id">必选参数，删除的私信id</param>
        /// <returns></returns>
        public DirectMessage DirectMessageDestory(string id)
        {
            var request = requestBase.SetHttpMethod(HttpMethodType.Post).SetUrl(string.Format(Urls.DirectMessageDestroy, id)).CommitRequest();
            var result = request.GetResponse();

            if (result.IsSuccess)
            {
                return JsonConvert.DeserializeObject<DirectMessage>(result.ResponseText);
            }
            else
                return null;
        }

        #endregion

        #region 帐号

        /// <summary>
        /// 网易通行证开通微博，当用户有通行证账号且未开通微博时，可以通过此API开通
        /// </summary>
        /// <param name="idNum">可选参数，身份证号，如身份证号不合法，则返回400</param>
        /// <param name="mobile">可选参数，手机号，如手机号不合法，则返回400</param>
        /// <param name="nikeName">可选参数，昵称，如果昵称不合法，则返回400</param>
        /// <param name="realName">可选参数，真实姓名，如真实姓名不合法，则返回400</param>
        /// <returns>是否开通成功状态</returns>
        public string Activate(string nikeName, string realName, string mobile, string idNum)
        {
            var request = requestBase.SetHttpMethod(HttpMethodType.Post).SetUrl(Urls.Activate).AddParameter(
                new Parameter("nick_name", nikeName),
                new Parameter("real_name", realName),
                new Parameter("mobile", mobile),
                new Parameter("id_num", idNum)
                ).CommitRequest();

            var result = request.GetResponse();

            if (result.IsSuccess && !string.IsNullOrWhiteSpace(result.ResponseText))
            {
                var r = new { id = "id", error = "", parameter = "", request = "" };

                var rt = JsonConvert.DeserializeAnonymousType(result.ResponseText, r);

                if (result.StatusCode == HttpStatusCode.OK)
                    return rt.id;
                else
                    return rt.error;
            }
            else
                return null;
        }

        /// <summary>
        /// 修改用户个人资料
        /// 本API只对高级第三方合作者开放，申请此API权限请发邮件到OpenAPI@yeah.net，未授权访问则返回403
        /// </summary>
        /// <param name="nikeName">可选参数，昵称，如果昵称不合法，则返回400</param>
        /// <param name="realName">可选参数，真实姓名，如真实姓名不合法，则返回400</param>
        /// <param name="description">可选参数，用户描述，如超过163个字符，则返回400</param>
        /// <param name="province">可选参数，用户省份，如省份不合法，则返回400</param>
        /// <param name="city">可选参数，用户城市，如城市不合法，则返回400</param>
        /// <returns></returns>
        public Users UpdateProfile(string nikeName = "", string realName = "", string description = "", string province = "", string city = "")
        {
            var request = requestBase.SetHttpMethod(HttpMethodType.Post).SetUrl(Urls.UpdateProfile).AddParameter(
                new Parameter("nick_name", nikeName),
                new Parameter("real_name", realName),
                new Parameter("description", description),
                new Parameter("province", province),
                new Parameter("city", city)).CommitRequest();

            var result = request.GetResponse();

            if (result.IsSuccess && !string.IsNullOrWhiteSpace(result.ResponseText))
                return JsonConvert.DeserializeObject<Users>(result.ResponseText);
            else
                return null;
        }

        /// <summary>
        /// 修改用户个人头像
        /// 本API只对高级第三方合作者开放，申请此API权限请发邮件到OpenAPI@yeah.net，未授权访问则返回403
        /// </summary>
        /// <param name="image">必选参数，图片路径。支持jpg、png、gif这三种图片格式，上传图片大小在4M以内</param>
        /// <returns></returns>
        public Users UpdateProfileImage(string image)
        {
            string imgUrl = UploadPic(image);
            var request = requestBase.SetHttpMethod(HttpMethodType.Post).SetUrl(Urls.UpdateProfielImage).AddParameter(
                new Parameter("image", imgUrl)
                ).CommitRequest();

            var result = request.GetResponse();

            if (result.IsSuccess && !string.IsNullOrWhiteSpace(result.ResponseText))
                return JsonConvert.DeserializeObject<Users>(result.ResponseText);
            else
                return null;
        }

        /// <summary>
        /// 返回当前登录用户未读的新消息数量
        /// </summary>
        /// <returns></returns>
        public string Latest()
        {
            var request = requestBase.SetHttpMethod(HttpMethodType.Get).SetUrl(Urls.Letest).CommitRequest();

            var result = request.GetResponse();

            if (result.IsSuccess && !string.IsNullOrWhiteSpace(result.ResponseText))
                return result.ResponseText;
            else
                return null;
        }

        /// <summary>
        /// 返回当前小时内剩余访问次数
        /// </summary>
        /// <returns></returns>
        public string RateLimitStatus()
        {
            var request = requestBase.SetHttpMethod(HttpMethodType.Get).SetUrl(Urls.RateLimitStatus).CommitRequest();
            var result = request.GetResponse();

            if (result.IsSuccess)
            {
                return result.ResponseText;
            }
            else
                return string.Empty;
        }

        #endregion

        #region 收藏

        /// <summary>
        /// 获取指定用户的收藏
        /// </summary>
        /// <param name="id">必选参数，可以为该用户的个性网址(screen_name)</param>
        /// <param name="count">返回微博数量，默认30，最大200</param>
        /// <param name="sinceId">分页参数，传微博ID,返回此条微博以前发的微博列表,不包含此条</param>
        /// <returns></returns>
        public List<Statues> Favorites(string id, int count = 30, string sinceId = "")
        {
            var request = requestBase.SetHttpMethod(HttpMethodType.Get).SetUrl(string.Format(Urls.Favorites, id)).AddParameter(
                new Parameter("count", count.ToString()), 
                new Parameter("since_id", sinceId)).CommitRequest();

            var result = request.GetResponse();
            if (result.IsSuccess)
            {
                return JsonConvert.DeserializeObject<List<Statues>>(result.ResponseText);
            }
            else
                return null;
        }

        /// <summary>
        /// 添加收藏
        /// </summary>
        /// <param name="id">必选参数，要收藏的微博ID</param>
        /// <returns></returns>
        public Statues FavoritesCreate(string id)
        {
            var request = requestBase.SetHttpMethod(HttpMethodType.Post).SetUrl(string.Format(Urls.FavoritesCreate, id)).CommitRequest();
            var result = request.GetResponse();

            if (result.IsSuccess)
            {
                return JsonConvert.DeserializeObject<Statues>(result.ResponseText);
            }
            else
                return null;
        }

        /// <summary>
        /// 删除当前用户的收藏
        /// </summary>
        /// <param name="id">必选参数，要删除的微博ID</param>
        /// <returns></returns>
        public Statues FavoritesDestroy(string id)
        {
            var request = requestBase.SetHttpMethod(HttpMethodType.Post).SetUrl(string.Format(Urls.FavoritesDestroy, id)).CommitRequest();
            var result = request.GetResponse();

            if (result.IsSuccess)
            {
                return JsonConvert.DeserializeObject<Statues>(result.ResponseText);
            }
            else
                return null;
        }

        #endregion

        #region 黑名单

        /// <summary>
        /// 阻止指定用户
        /// </summary>
        /// <param name="userId">可选参数. 用户ID，主要是用来区分用户ID跟微博昵称相同产生歧义的情况</param>
        /// <param name="screenName">可选参数，该用户的个性网址，也可以传user_id</param>
        /// <exception cref="System.ArgumentException">user_id 和 screen_name 不能同时为空。</exception>
        /// <returns></returns>
        public Users BlocksCreate(string userId = "", string screenName = "")
        {
            var request = requestBase.SetHttpMethod(HttpMethodType.Post).SetUrl(Urls.BlocksCreate).AddParameter(
                new Parameter("user_id", userId),
                new Parameter("screen_name", screenName)).CommitRequest();

            var result = request.GetResponse();
            if (result.IsSuccess)
            {
                return JsonConvert.DeserializeObject<Users>(result.ResponseText);
            }
            else
                return null;
        }

        /// <summary>
        /// 取消已阻止的用户，即将该用户移除黑名单
        /// </summary>
        /// <param name="userId">可选参数. 用户ID，主要是用来区分用户ID跟微博昵称相同产生歧义的情况</param>
        /// <param name="screenName">可选参数，该用户的个性网址，也可以传user_id</param>
        /// <returns></returns>
        public Users BlocksDestroy(string userId = "", string screenName = "")
        {
            var request = requestBase.SetHttpMethod(HttpMethodType.Post).SetUrl(Urls.BlocksDestroy).AddParameter(
                new Parameter("user_id", userId),
                new Parameter("screen_name", screenName)).CommitRequest();

            var result = request.GetResponse();
            if (result.IsSuccess)
            {
                return JsonConvert.DeserializeObject<Users>(result.ResponseText);
            }
            else
                return null;
        }

        /// <summary>
        /// 判断是否已经阻止用户,如已阻止此用户则返回用户信息，如未阻止则返回状态404，同时提示“此用户未被加入黑名单”
        /// </summary>
        /// <param name="userId">可选参数. 用户ID，主要是用来区分用户ID跟微博昵称相同产生歧义的情况</param>
        /// <param name="screenName">可选参数，该用户的个性网址，也可以传user_id</param>
        /// <returns></returns>
        public Users BlocksExits(string userId = "", string screenName = "")
        {
            var request = requestBase.SetHttpMethod(HttpMethodType.Post).SetUrl(Urls.BlocksExists).AddParameter(
               new Parameter("user_id", userId),
               new Parameter("screen_name", screenName)).CommitRequest();

            var result = request.GetResponse();
            if (result.IsSuccess)
            {
                return JsonConvert.DeserializeObject<Users>(result.ResponseText);
            }
            else
                return null;
        }

        /// <summary>
        /// 返回当前登录用户屏蔽的用户列表
        /// </summary>
        /// <returns></returns>
        public List<Users> Blocking()
        {
            var request = requestBase.SetHttpMethod(HttpMethodType.Get).SetUrl(Urls.BlocksBlocking).CommitRequest();
            var result = request.GetResponse();

            if (result.IsSuccess)
            {
                return JsonConvert.DeserializeObject<List<Users>>(result.ResponseText);
            }
            else
                return null;
        }

        /// <summary>
        /// 已阻止的Id列表
        /// </summary>
        /// <exception cref="System.NotImplementedException">该方法未实现</exception>
        /// <returns></returns>
        public List<string> BlockingIds()
        {
            // todo: 已阻止Id 列表
            throw new NotImplementedException();
        }

        #endregion

        #region 地址位置相关

        /// <summary>
        /// 返回指定位置附近或者符合搜索关键字的地点列表
        /// </summary>
        /// <param name="lat">可选参数，即纬度。范围在+90.0 到 -90.0，如果超出这个范围则忽略该值，必须与long参数一起使用，否则忽略该值</param>
        /// <param name="longGeo">可选参数,即经度。范围在+180.0到-180.0，如果超出这个范围则忽略该值，必须与lat参数一起使用，否则忽略该值</param>
        /// <param name="count">可选参数，返回数据的个数，默认为10，最大为50</param>
        /// <param name="q">选参数，搜索关键字，必须与经纬度（lat,long）参数同时使用才有效，,根据定位的数据在用户所在的城市搜索相应的POI，如没有经纬度参数或无结果返回404</param>
        /// <returns></returns>
        public List<Venue> GetVenues( int count = 10, string q = "",double lat = 0, double longGeo = 0)
        {
            var request = requestBase.SetHttpMethod(HttpMethodType.Get).SetUrl(Urls.Venues).AddParameter(
                new Parameter[] {
                    new Parameter("lat", lat.ToString()),
                    new Parameter("long", longGeo.ToString()),
                    new Parameter("count", count.ToString()),
                    new Parameter("q", q)
                }).CommitRequest();

            var result = request.GetResponse();
            if (result.IsSuccess)
            {
                var Venues = new { venues = new List<Venue>() };

                return JsonConvert.DeserializeAnonymousType(result.ResponseText, Venues).venues;
            }
            else
                return null;
        }

        /// <summary>
        /// 通过经纬度或POI返回与地理位置相关的微博列表，如传经纬度则返回附近的微博列表，传POI的ID则返回此POI下的微博列表
        /// </summary>
        /// <param name="lat">可选参数，即纬度。范围在+90.0 到 -90.0，如果超出这个范围则忽略该值，必须与long参数一起使用，否则忽略该值</param>
        /// <param name="longGeo">可选参数,即经度。范围在+180.0到-180.0，如果超出这个范围则忽略该值，必须与lat参数一起使用，否则忽略该值</param>
        /// <param name="vid">可选参数,即POI的id，单独使用时值返回包含此vid的微博。如果经纬度也同时传入，则将两种微博（包含vid或经纬度的）一起返回，按照发微博的时间倒序排列。如果根据vid找不到相应的poi且无定位参数时则返回404</param>
        /// <param name="sinceId">可选参数，该参数需传cursor_id,返回此条索引之前发的微博列表,不包含此条</param>
        /// <param name="maxId">可选参数，该参数需传cursor_id,返回此条索引之后发的微博列表，包含此条</param>
        /// <param name="count">可选参数，返回微博的个数，默认为30，最大为200</param>
        /// <returns></returns>
        public List<Statues> LocationTimeLine(int count = 30, double lat = 0, double longGeo = 0, string vid = "", string sinceId = "", string maxId = "")
        {
            var request = requestBase.SetHttpMethod(HttpMethodType.Get).SetUrl(Urls.LocationTimeLine).AddParameter(
                new Parameter[]{
                    new Parameter("lat", lat.ToString()),
                    new Parameter("long", longGeo.ToString()),
                    new Parameter("vid", vid),
                    new Parameter("count", count.ToString()),
                    new Parameter("since_id", sinceId),
                    new Parameter("max_id", maxId)
                }).CommitRequest();
            var result = request.GetResponse();

            if (result.IsSuccess)
            {
                return JsonConvert.DeserializeObject<List<Statues>>(result.ResponseText);
            }
            else
                return null;
        }

        #endregion

        #region 搜索

        /// <summary>
        /// 搜索
        /// </summary>
        /// <param name="q">必选参数，关键字,最大长度25,如果以#起始的关键字会作为tag搜索精确匹配</param>
        /// <param name="page">可选参数，当前页数，默认为第一页</param>
        /// <param name="perPage">可选参数，返回数量,最大20</param>
        /// <returns></returns>
        public string Search(string q, int page = 1, int perPage = 20)
        {
            var request = requestBase.SetHttpMethod(HttpMethodType.Get).SetUrl(Urls.Search).AddParameter(
                new Parameter[] {
                    new Parameter("q", q),
                    new Parameter("page", page.ToString()),
                    new Parameter("per_page", perPage.ToString())
                }).CommitRequest();

            var result = request.GetResponse();
            if (result.IsSuccess)
            {
                return result.ResponseText;
            }
            else
                return null;
        }

        /// <summary>
        /// 搜索微博
        /// </summary>
        /// <param name="q">必选参数，关键字,最大长度25,如果以#起始的关键字会作为tag搜索精确匹配</param>
        /// <param name="page">可选参数，当前页数，默认为第一页</param>
        /// <param name="perPage">可选参数，返回数量,最大20</param>
        /// <param name="trimUse">可选参数，值为true时返回的user对象只包含id属性，该属性能在一定程度上减少返回的数据量</param>
        /// <returns></returns>
        public List<Statues> SearchStatus(string q, int page = 1, int perPage = 20, bool trimUse = true)
        {
            var request = requestBase.SetHttpMethod(HttpMethodType.Get).SetUrl(Urls.StatuesSearch).AddParameter(
                new Parameter[] {
                    new Parameter("q", q),
                    new Parameter("page", page.ToString()),
                    new Parameter("per_page", perPage.ToString()),
                    new Parameter("trim_user", trimUse ? "true" : "false")
                }).CommitRequest();

            var result = request.GetResponse();
            if (result.IsSuccess)
            {
                return JsonConvert.DeserializeObject<List<Statues>>(result.ResponseText);
            }
            else
                return null;
        }

        /// <summary>
        /// 搜索用户
        /// </summary>
        /// <param name="q">必选参数，关键字,最大长度25</param>
        /// <param name="page">可选参数，当前页数，默认为第一页</param>
        /// <param name="perPage">可选参数，返回数量,最大20</param>
        /// <returns></returns>
        public List<Users> SearchUser(string q, int page = 1, int perPage = 20)
        {
            var request = requestBase.SetHttpMethod(HttpMethodType.Get).SetUrl(Urls.UserSearch).AddParameter(
                new Parameter[] {
                    new Parameter("q", q),
                    new Parameter("page", page.ToString()),
                    new Parameter("per_page", perPage.ToString())
                }).CommitRequest();

            var result = request.GetResponse();
            if (result.IsSuccess)
            {
                return JsonConvert.DeserializeObject<List<Users>>(result.ResponseText);
            }
            else
                return null;
        }

        #endregion


#else

        #region 微博列表

        /// <summary>
        /// 获取公共微博列表
        /// </summary>
        /// <param name="trimUser">可选参数，值为true时返回的user对象只包含id属性</param>
        /// <returns>微博列表</returns>
        public List<Statues> GetPublicTimeLine()
        {
            return GetPublicTimeLine(false);
        }

        /// <summary>
        /// 获取公共微博列表
        /// </summary>
        /// <param name="url">地址</param>
        /// <param name="trimUser">可选参数，值为true时返回的user对象只包含id属性</param>
        /// <returns>微博列表</returns>
        public List<Statues> GetPublicTimeLine(bool trimUser)
        {
            var ptlRequest = requestBase.SetUrl(Urls.PublicTimeLine).AddParameter(new Parameter("trim_user", trimUser ? "true" : "false")).CommitRequest();
            var result = ptlRequest.GetResponse();

            if (result.IsSuccess && result.ResponseText != null)
            {
                return JsonConvert.DeserializeObject<List<Statues>>(result.ResponseText);
            }
            else
                return null;
        }

        /// <summary>
        /// 取得当前登录用户的微博列表
        /// </summary>
        /// <returns>微博列表</returns>
        public List<Statues> GetHomeTimeLine()
        {
            return GetHomeTimeLine(null);
        }

        /// <summary>
        /// 取得当前登录用户的微博列表
        /// </summary>
        /// <param name="trimUser">值为true时返回的user对象只包含id属性，该属性能在一定程度上减少返回的数据量</param>
        /// <returns>微博列表</returns>
        public List<Statues> GetHomeTimeLine(bool trimUser)
        {
            return GetHomeTimeLine(null, null, trimUser, 30);
        }

        /// <summary>
        /// 取得当前登录用户的微博列表
        /// </summary>
        /// <param name="count">数量，默认为30条，最大为200条</param>
        /// <returns>微博列表</returns>
        public List<Statues> GetHomeTimeLine(int count)
        {
            return GetHomeTimeLine(null, null, true, count);
        }

        /// <summary>
        /// 取得当前登录用户的微博列表
        /// </summary>
        /// <param name="sinceId">该参数需传cursor_id,返回此条索引之前发的微博列表,不包含此条</param>
        /// <returns>微博列表</returns>
        public List<Statues> GetHomeTimeLine(string sinceId)
        {
            return GetHomeTimeLine(sinceId, null);
        }

        /// <summary>
        /// 取得当前登录用户的微博列表
        /// </summary>
        /// <param name="sinceId">该参数需传cursor_id,返回此条索引之前发的微博列表,不包含此条</param>
        /// <param name="maxId">该参数需传cursor_id,返回此条索引之后发的微博列表，包含此条</param>
        /// <returns>微博列表</returns>
        public List<Statues> GetHomeTimeLine(string sinceId, string maxId)
        {
            return GetHomeTimeLine(sinceId, maxId, true);
        }

        /// <summary>
        /// 取得当前登录用户的微博列表
        /// </summary>
        /// <param name="sinceId">该参数需传cursor_id,返回此条索引之前发的微博列表,不包含此条</param>
        /// <param name="maxId">该参数需传cursor_id,返回此条索引之后发的微博列表，包含此条</param>
        /// <param name="trimUser">值为true时返回的user对象只包含id属性，该属性能在一定程度上减少返回的数据量</param>
        /// <returns>微博列表</returns>
        public List<Statues> GetHomeTimeLine(string sinceId, string maxId, bool trimUser)
        {
            return GetHomeTimeLine(sinceId, maxId, trimUser, 30);
        }

        /// <summary>
        /// 取得当前登录用户的微博列表
        /// </summary>
        /// <param name="sinceId">该参数需传cursor_id,返回此条索引之前发的微博列表,不包含此条</param>
        /// <param name="maxId">该参数需传cursor_id,返回此条索引之后发的微博列表，包含此条</param>
        /// <param name="trimUser">值为true时返回的user对象只包含id属性，该属性能在一定程度上减少返回的数据量</param>
        /// <param name="count">数量，默认为30条，最大为200条</param>
        /// <returns>微博列表</returns>
        public List<Statues> GetHomeTimeLine(string sinceId, string maxId, bool trimUser, int count)
        {
            if (count > 200)
                throw new ArgumentException("最大数量为200条", "count");

            var request = requestBase.SetUrl(Urls.HomeTimeLine).AddParameter(
                new Parameter[] {
                    new Parameter("count", count.ToString()),
                    new Parameter("trim_user", trimUser ? "true" : "false"),
                    new Parameter("since_id", sinceId),
                    new Parameter("max_id", maxId)
                }).CommitRequest();

            var result = request.GetResponse();

            if (result.IsSuccess && result.ResponseText != null)
            {
                return JsonConvert.DeserializeObject<List<Statues>>(result.ResponseText);
            }
            else
                return null;
        }

        /// <summary>
        /// 获取指定微博的转发列表
        /// </summary>
        /// <param name="id">必选参数，指定的微博id</param>
        /// <returns>微博列表</returns>
        public List<Statues> GetRetweets(string id)
        {
            return GetRetweets(id, 30);
        }

        /// <summary>
        /// 获取指定微博的转发列表
        /// </summary>
        /// <param name="id">必选参数，指定的微博id</param>
        /// <param name="count">可选参数，数量，默认为30条，最大为200条</param>
        /// <returns>微博列表</returns>
        public List<Statues> GetRetweets(string id, int count)
        {
            return GetRetweets(id, count, null);
        }

        /// <summary>
        /// 获取指定微博的转发列表
        /// </summary>
        /// <param name="id">必选参数，指定的微博id</param>
        /// <param name="count">选参数，数量，默认为30条，最大为200条</param>
        /// <param name="trimUser">可选参数，值为true时返回的user对象只包含id属性，该参数能在一定程度上减少返回的数据量</param>
        /// <returns>微博列表</returns>
        public List<Statues> GetRetweets(string id, int count, bool trimUser)
        {
            return GetRetweets(id, count, null, null, trimUser);
        }

        /// <summary>
        /// 获取指定微博的转发列表
        /// </summary>
        /// <param name="id">必选参数，指定的微博id</param>
        /// <param name="count">可选参数，数量，默认为30条，最大为200条</param>
        /// <param name="sinceId">可选参数，该参数需传微博id，返回此条索引之后发的微博列表，不包含此条</param>
        /// <returns>微博列表</returns>
        public List<Statues> GetRetweets(string id, int count, string sinceId)
        {
            return GetRetweets(id, count, sinceId, null);
        }

        /// <summary>
        /// 获取指定微博的转发列表
        /// </summary>
        /// <param name="id">必选参数，指定的微博id</param>
        /// <param name="count">选参数，数量，默认为30条，最大为200条</param>
        /// <param name="sinceId">可选参数，该参数需传微博id，返回此条索引之后发的微博列表，不包含此条</param>
        /// <param name="maxId">可选参数，该参数需传微博id，返回此条微博之前发的微博列表，包含此条</param>
        /// <returns>微博列表</returns>
        public List<Statues> GetRetweets(string id, int count, string sinceId, string maxId)
        {
            return GetRetweets(id, count, sinceId, maxId, true);
        }

        /// <summary>
        /// 获取指定微博的转发列表
        /// </summary>
        /// <param name="id">必选参数，指定的微博id</param>
        /// <param name="count">选参数，数量，默认为30条，最大为200条</param>
        /// <param name="sinceId">可选参数，该参数需传微博id，返回此条索引之后发的微博列表，不包含此条</param>
        /// <param name="maxId">可选参数，该参数需传微博id，返回此条微博之前发的微博列表，包含此条</param>
        /// <param name="trimUser">可选参数，值为true时返回的user对象只包含id属性，该参数能在一定程度上减少返回的数据量</param>
        /// <returns></returns>
        public List<Statues> GetRetweets(string id, int count, string sinceId, string maxId, bool trimUser)
        {
            var request = requestBase.SetHttpMethod(HttpMethodType.Get).SetUrl(string.Format(Urls.Retweets, id)).AddParameter(
                new Parameter[] {
                    new Parameter("count", count.ToString()),
                    new Parameter("since_id", sinceId),
                    new Parameter("max_id", maxId),
                    new Parameter("trim_user", trimUser ? "true" : "false")
                }).CommitRequest();

            var result = request.GetResponse();
            if (result.IsSuccess && result.ResponseText != null)
            {
                return JsonConvert.DeserializeObject<List<Statues>>(result.ResponseText);
            }
            else
                return null;
        }

        /// <summary>
        /// 获取@评论当前登录用户的微博列表
        /// </summary>
        /// <returns>微博列表</returns>
        public List<Statues> GetMentions()
        {
            return GetMentions(null, null, true, 30);
        }

        /// <summary>
        /// 获取@评论当前登录用户的微博列表
        /// </summary>
        /// <param name="trimUser">值为true时返回的user对象只包含id属性，该参数能在一定程度上减少返回的数据量</param>
        /// <returns>微博列表</returns>
        public List<Statues> GetMentions(bool trimUser)
        {
            return GetMentions(null, null, trimUser, 30);
        }

        /// <summary>
        /// 获取@评论当前登录用户的微博列表
        /// </summary>
        /// <param name="count">数量，默认为30条，最大为200条</param>
        /// <returns>微博列表</returns>
        public List<Statues> GetMentions(int count)
        {
            return GetMentions(null, null, true, count);
        }

        /// <summary>
        /// 获取@评论当前登录用户的微博列表
        /// </summary>
        /// <param name="trimUser">值为true时返回的user对象只包含id属性，该参数能在一定程度上减少返回的数据量</param>
        /// <param name="count">数量，默认为30条，最大为200条</param>
        /// <returns>微博列表</returns>
        public List<Statues> GetMentions(bool trimUser, int count)
        {
            return GetMentions(null, null, trimUser, count);
        }

        /// <summary>
        /// 获取@评论当前登录用户的微博列表
        /// </summary>
        /// <param name="sinceId">该参数需传cursor_id,返回此条索引之前发的微博列表,不包含此条</param>
        /// <param name="maxId">该参数需传cursor_id,返回此条索引之后发的微博列表，包含此条</param>
        /// <param name="trimUser">值为true时返回的user对象只包含id属性，该参数能在一定程度上减少返回的数据量</param>
        /// <returns>微博列表</returns>
        public List<Statues> GetMentions(string sinceId, string maxId, bool trimUser)
        {
            return GetMentions(sinceId, maxId, trimUser, 30);
        }

        /// <summary>
        /// 获取@评论当前登录用户的微博列表
        /// </summary>
        /// <param name="sinceId">该参数需传cursor_id,返回此条索引之前发的微博列表,不包含此条</param>
        /// <param name="maxId">该参数需传cursor_id,返回此条索引之后发的微博列表，包含此条</param>
        /// <param name="trimUser">值为true时返回的user对象只包含id属性，该参数能在一定程度上减少返回的数据量</param>
        /// <param name="count">数量，默认为30条，最大为200条</param>
        /// <returns>微博列表</returns>
        public List<Statues> GetMentions(string sinceId, string maxId, bool trimUser, int count)
        {
            if (count > 200)
                throw new ArgumentException("最大数量为200条", "count");

            var request = requestBase.SetUrl(Urls.Mentions).AddParameter(
                new Parameter[] {
                    new Parameter("count", count.ToString()),
                    new Parameter("trim_user", trimUser ? "true" : "false"),
                    new Parameter("since_id", sinceId),
                    new Parameter("max_id", maxId)
                }).CommitRequest();

            var result = request.GetResponse();

            if (result.IsSuccess && result.ResponseText != null)
            {
                return JsonConvert.DeserializeObject<List<Statues>>(result.ResponseText);
            }
            else
                return null;
        }

        /// <summary>
        /// 获取指定用户的微博列表
        /// </summary>
        /// <param name="userId">可选参数. 用户ID，主要是用来区分用户ID跟微博昵称相同产生歧义的情况</param>
        /// <returns>微博列表</returns>
        public List<Statues> GetUserTimeLine(string userId)
        {
            return GetUserTimeLine(userId, null);
        }

        /// <summary>
        /// 获取指定用户的微博列表
        /// </summary>
        /// <param name="screenName">可选参数，可以传user_id或screen_name</param>
        /// <param name="count">可选参数，数量，默认为30条，最大为200条</param>
        /// <returns>微博列表</returns>
        public List<Statues> GetUserTimeLine(string screenName, int count)
        {
            return GetUserTimeLine(null, null, null, null, screenName, true, count);
        }

        /// <summary>
        /// 获取指定用户的微博列表
        /// </summary>
        /// <param name="screenName">可选参数，可以传user_id或screen_name</param>
        /// <param name="trimUser">可选参数，值为true时返回的user对象只包含id属性，该属性能在一定程度上减少返回的数据量</param>
        /// <param name="count">可选参数，数量，默认为30条，最大为200条</param>
        /// <returns>微博列表</returns>
        public List<Statues> GetUserTimeLine(string screenName, bool trimUser, int count)
        {
            return GetUserTimeLine(null, null, null, null, screenName, trimUser, count);
        }

        /// <summary>
        /// 获取指定用户的微博列表
        /// </summary>
        /// <param name="userId">可选参数. 用户ID，主要是用来区分用户ID跟微博昵称相同产生歧义的情况</param>
        /// <param name="name">可选参数，用户昵称</param>
        /// <returns>微博列表</returns>
        public List<Statues> GetUserTimeLine(string userId, string name)
        {
            return GetUserTimeLine(null, userId, name);
        }

        /// <summary>
        /// 获取指定用户的微博列表
        /// </summary>
        /// <param name="maxId">可选参数，该参数需传cursor_id,返回此条索引之后发的微博列表，包含此条</param>
        /// <param name="userId">可选参数. 用户ID，主要是用来区分用户ID跟微博昵称相同产生歧义的情况</param>
        /// <param name="name">可选参数，用户昵称</param>
        /// <returns>微博列表</returns>
        public List<Statues> GetUserTimeLine(string maxId, string userId, string name)
        {
            return GetUserTimeLine(null, maxId, userId, name, null);
        }

        /// <summary>
        /// 获取指定用户的微博列表
        /// </summary>
        /// <param name="sinceId">可选参数，该参数需传cursor_id,返回此条索引之前发的微博列表,不包含此条</param>
        /// <param name="maxId">可选参数，该参数需传cursor_id,返回此条索引之后发的微博列表，包含此条</param>
        /// <param name="userId">可选参数. 用户ID，主要是用来区分用户ID跟微博昵称相同产生歧义的情况</param>
        /// <param name="name">可选参数，用户昵称</param>
        /// <returns>微博列表</returns>
        public List<Statues> GetUserTimeLine(string sinceId, string maxId, string userId, string name)
        {
            return GetUserTimeLine(sinceId, maxId, userId, name, null);
        }

        /// <summary>
        /// 获取指定用户的微博列表
        /// </summary>
        /// <param name="sinceId">可选参数，该参数需传cursor_id,返回此条索引之前发的微博列表,不包含此条</param>
        /// <param name="maxId">可选参数，该参数需传cursor_id,返回此条索引之后发的微博列表，包含此条</param>
        /// <param name="userId">可选参数. 用户ID，主要是用来区分用户ID跟微博昵称相同产生歧义的情况</param>
        /// <param name="name">可选参数，用户昵称</param>
        /// <param name="screenName">可选参数，可以传user_id或screen_name</param>
        /// <returns>微博列表</returns>
        public List<Statues> GetUserTimeLine(string sinceId, string maxId,
            string userId, string name, string screenName)
        {
            return GetUserTimeLine(sinceId, maxId, userId, name, screenName, true);
        }

        /// <summary>
        /// 获取指定用户的微博列表
        /// </summary>
        /// <param name="sinceId">可选参数，该参数需传cursor_id,返回此条索引之前发的微博列表,不包含此条</param>
        /// <param name="maxId">可选参数，该参数需传cursor_id,返回此条索引之后发的微博列表，包含此条</param>
        /// <param name="userId">可选参数. 用户ID，主要是用来区分用户ID跟微博昵称相同产生歧义的情况</param>
        /// <param name="name">可选参数，用户昵称</param>
        /// <param name="screenName">可选参数，可以传user_id或screen_name</param>
        /// <param name="trimUser">可选参数，值为true时返回的user对象只包含id属性，该属性能在一定程度上减少返回的数据量</param>
        /// <returns>微博列表</returns>
        public List<Statues> GetUserTimeLine(string sinceId, string maxId,
            string userId, string name, string screenName, bool trimUser)
        {
            return GetUserTimeLine(sinceId, maxId, userId, name, screenName, trimUser, 30);
        }

        /// <summary>
        /// 获取指定用户的微博列表
        /// </summary>
        /// <param name="sinceId">可选参数，该参数需传cursor_id,返回此条索引之前发的微博列表,不包含此条</param>
        /// <param name="maxId">可选参数，该参数需传cursor_id,返回此条索引之后发的微博列表，包含此条</param>
        /// <param name="userId">可选参数. 用户ID，主要是用来区分用户ID跟微博昵称相同产生歧义的情况</param>
        /// <param name="name">可选参数，用户昵称</param>
        /// <param name="screenName">可选参数，可以传user_id或screen_name</param>
        /// <param name="trimUser">可选参数，值为true时返回的user对象只包含id属性，该属性能在一定程度上减少返回的数据量</param>
        /// <param name="count">可选参数，数量，默认为30条，最大为200条</param>
        /// <returns>微博列表</returns>
        public List<Statues> GetUserTimeLine(string sinceId, string maxId,
            string userId, string name, string screenName, bool trimUser, int count)
        {
            var request = requestBase.SetUrl(Urls.UserTimeLine).AddParameter(
               new Parameter[] {
                    new Parameter("name", name),
                    new Parameter("screen_name", screenName),
                    new Parameter("user_id", userId),
                    new Parameter("count", count.ToString()),
                    new Parameter("trim_user", trimUser ? "true" : "false"),
                    new Parameter("since_id", sinceId),
                    new Parameter("max_id", maxId)
                }).CommitRequest();

            var result = request.GetResponse();

            if (result.IsSuccess && result.ResponseText != null)
            {
                return JsonConvert.DeserializeObject<List<Statues>>(result.ResponseText);
            }
            else
                return null;
        }

        /// <summary>
        /// 获取当前登录用户所发微博被转发的列表
        /// </summary>
        /// <returns></returns>
        public List<Statues> GetRetweetsOfMe()
        {
            return GetRetweetsOfMe(null);
        }

        /// <summary>
        /// 获取当前登录用户所发微博被转发的列表
        /// </summary>
        /// <param name="sinceId">可选参数，该参数需传cursor_id,返回此条索引之前发的微博列表,不包含此条</param>
        /// <returns></returns>
        public List<Statues> GetRetweetsOfMe(string sinceId)
        {
            return GetRetweetsOfMe(sinceId, 30);
        }

        /// <summary>
        /// 获取当前登录用户所发微博被转发的列表
        /// </summary>
        /// <param name="count">可选参数，数量，默认为30条，最大为200条</param>
        /// <returns></returns>
        public List<Statues> GetRetweetsOfMe(int count)
        {
            return GetRetweetsOfMe(null, count);
        }

        /// <summary>
        /// 获取当前登录用户所发微博被转发的列表
        /// </summary>
        /// <param name="sinceId">可选参数，该参数需传cursor_id,返回此条索引之前发的微博列表,不包含此条</param>
        /// <param name="count">可选参数，数量，默认为30条，最大为200条</param>
        /// <returns></returns>
        public List<Statues> GetRetweetsOfMe(string sinceId, int count)
        {
            if (count > 200)
                throw new ArgumentException("最大数量为200条", "count");

            var request = requestBase.SetUrl(Urls.RetweetsOfMe).AddParameter(
                new Parameter[] {
                    new Parameter("count", count.ToString()),
                    new Parameter("since_id", sinceId)
                }).CommitRequest();

            var result = request.GetResponse();

            if (result.IsSuccess)
            {
                // reference: http://stackoverflow.com/questions/612689/a-generic-list-of-anonymous-class
                var retweets = new { created_at = "created_at", retweeted_status = new Statues() };
                var retweets1 = new { created_at = "created_at1", retweeted_status = new Statues() };

                var rtArray = new[] { retweets, retweets1 };

                var lst = JsonConvert.DeserializeAnonymousType(result.ResponseText, rtArray);

                List<Statues> stlst = new List<Statues>();
                foreach (var s in lst)
                {
                    stlst.Add(s.retweeted_status);
                }

                return stlst;
            }
            else
                return null;
        }

        /// <summary>
        /// 获取当前登录用户发出的评论列表
        /// </summary>
        /// <returns></returns>
        public List<Statues> GetCommentsByMe()
        {
            return GetCommentsByMe(null, null, true, 30);
        }

        /// <summary>
        /// 获取当前登录用户发出的评论列表
        /// </summary>
        /// <param name="count">选参数，数量，默认为30条，最大为200条</param>
        /// <returns></returns>
        public List<Statues> GetCommentsByMe(int count)
        {
            return GetCommentsByMe(true, count);
        }

        /// <summary>
        /// 获取当前登录用户发出的评论列表
        /// </summary>
        /// <param name="sinceId">可选参数，该参数需传cursor_id,返回此条索引之后发的微博列表，包含此条</param>
        /// <param name="maxId">可选参数，该参数需传cursor_id,返回此条索引之后发的微博列表，包含此条</param>
        /// <param name="trimUser">可选参数，值为true时返回的user对象只包含id属性，该属性能在一定程度上减少返回的数据量。默认为true</param>
        /// <returns></returns>
        public List<Statues> GetCommentsByMe(string sinceId, string maxId, bool trimUser)
        {
            return GetCommentsByMe(sinceId, maxId, trimUser, 30);
        }

        /// <summary>
        /// 获取当前登录用户发出的评论列表
        /// </summary>
        /// <param name="trimUser">可选参数，值为true时返回的user对象只包含id属性，该属性能在一定程度上减少返回的数据量。默认为true</param>
        /// <param name="count">选参数，数量，默认为30条，最大为200条</param>
        /// <returns></returns>
        public List<Statues> GetCommentsByMe(bool trimUser, int count)
        {
            return GetCommentsByMe(null, null, trimUser, count);
        }

        /// <summary>
        /// 获取当前登录用户发出的评论列表
        /// </summary>
        /// <param name="sinceId">可选参数，该参数需传cursor_id,返回此条索引之后发的微博列表，包含此条</param>
        /// <param name="maxId">可选参数，该参数需传cursor_id,返回此条索引之后发的微博列表，包含此条</param>
        /// <param name="trimUser">可选参数，值为true时返回的user对象只包含id属性，该属性能在一定程度上减少返回的数据量。默认为true</param>
        /// <param name="count">选参数，数量，默认为30条，最大为200条</param>
        /// <returns></returns>
        public List<Statues> GetCommentsByMe(string sinceId, string maxId, bool trimUser, int count)
        {
            if (count > 200)
                throw new ArgumentException("最大数量为200条", "count");

            var request = requestBase.SetUrl(Urls.CommentsByMe).AddParameter(
                new Parameter[] {
                    new Parameter("count", count.ToString()),
                    new Parameter("trim_user", trimUser ? "true" : "false"),
                    new Parameter("since_id", sinceId),
                    new Parameter("max_id", maxId)
                }).CommitRequest();

            var result = request.GetResponse();

            if (result.IsSuccess && result.ResponseText != null)
            {
                return JsonConvert.DeserializeObject<List<Statues>>(result.ResponseText);
            }
            else
                return null;
        }

        /// <summary>
        /// 获取当前登录用户收到的评论列表
        /// </summary>
        /// <returns></returns>
        public List<Statues> GetCommentsToMe()
        {
            return GetCommentsToMe(30);
        }

        /// <summary>
        /// 获取当前登录用户收到的评论列表
        /// </summary>
        /// <param name="count">可选参数，数量，默认为30条，最大为200条</param>
        /// <returns></returns>
        public List<Statues> GetCommentsToMe(int count)
        {
            return GetCommentsToMe(true, count);
        }

        /// <summary>
        /// 获取当前登录用户收到的评论列表
        /// </summary>
        /// <param name="trimUser">可选参数，值为true时返回的user对象只包含id属性，该属性能在一定程度上减少返回的数据量。默认为true</param>
        /// <param name="count">可选参数，数量，默认为30条，最大为200条</param>
        /// <returns></returns>
        public List<Statues> GetCommentsToMe(bool trimUser, int count)
        {
            return GetCommentsToMe(null, null, trimUser, count);
        }

        /// <summary>
        /// 获取当前登录用户收到的评论列表
        /// </summary>
        /// <param name="sinceId">可选参数，该参数需传cursor_id,返回此条索引之前发的微博列表,不包含此条</param>
        /// <param name="maxId">可选参数，该参数需传cursor_id,返回此条索引之后发的微博列表，包含此条</param>
        /// <param name="trimUser">可选参数，值为true时返回的user对象只包含id属性，该属性能在一定程度上减少返回的数据量。默认为true</param>
        /// <returns></returns>
        public List<Statues> GetCommentsToMe(string sinceId, string maxId, bool trimUser)
        {
            return GetCommentsToMe(sinceId, maxId, trimUser, 30);
        }

        /// <summary>
        /// 获取当前登录用户收到的评论列表
        /// </summary>
        /// <param name="sinceId">可选参数，该参数需传cursor_id,返回此条索引之前发的微博列表,不包含此条</param>
        /// <param name="maxId">可选参数，该参数需传cursor_id,返回此条索引之后发的微博列表，包含此条</param>
        /// <param name="trimUser">可选参数，值为true时返回的user对象只包含id属性，该属性能在一定程度上减少返回的数据量。默认为true</param>
        /// <param name="count">可选参数，数量，默认为30条，最大为200条</param>
        /// <returns></returns>
        public List<Statues> GetCommentsToMe(string sinceId, string maxId, bool trimUser, int count)
        {
            if (count > 200)
                throw new ArgumentException("最大数量为200条", "count");

            var request = requestBase.SetUrl(Urls.HomeTimeLine).AddParameter(
                new Parameter[] {
                    new Parameter("count", count.ToString()),
                    new Parameter("trim_user", trimUser ? "true" : "false"),
                    new Parameter("since_id", sinceId),
                    new Parameter("max_id", maxId)
                }).CommitRequest();

            var result = request.GetResponse();

            if (result.IsSuccess && result.ResponseText != null)
            {
                return JsonConvert.DeserializeObject<List<Statues>>(result.ResponseText);
            }
            else
                return null;
        }

        #endregion

        #region 微博

        /// <summary>
        /// 发布一条微博。
        /// </summary>
        /// <param name="statues">必选参数，微博内容，不得超过163个字符</param>
        /// <exception cref="System.ArgumentNullException">status 为NULL</exception>
        /// <exception cref="System.ArgumentOutOfRangeException">Status.Text 超过163个字符</exception>
        /// <returns></returns>
        public Statues Update(Statues status)
        {
            return Update(status, 0, 0);
        }

        /// <summary>
        /// 发布一条微博。
        /// </summary>
        /// <param name="statues">必选参数，微博内容，不得超过163个字符</param>
        /// <param name="lat">选参数，即纬度。范围在+90.0 到 -90.0，如果超出这个范围则忽略该值，必须与long参数一起使用，否则忽略该值。只有当用户的geo_enable为true时才有效</param>
        /// <param name="longGeo">可选参数,即经度。范围在+180.0到-180.0，如果超出这个范围则忽略该值，必须与lat参数一起使用，否则忽略该值。只有当用户的geo_enable为true时才有效</param>
        /// <exception cref="System.ArgumentNullException">status 为NULL</exception>
        /// <exception cref="System.ArgumentOutOfRangeException">Status.Text 超过163个字符</exception>
        /// <returns></returns>
        public Statues Update(Statues status, double lat, double longGeo)
        {
            return Update(status, lat, longGeo, null);
        }

        /// <summary>
        /// 发布一条微博。
        /// </summary>
        /// <param name="statues">必选参数，微博内容，不得超过163个字符</param>
        /// <param name="lat">选参数，即纬度。范围在+90.0 到 -90.0，如果超出这个范围则忽略该值，必须与long参数一起使用，否则忽略该值。只有当用户的geo_enable为true时才有效</param>
        /// <param name="longGeo">可选参数,即经度。范围在+180.0到-180.0，如果超出这个范围则忽略该值，必须与lat参数一起使用，否则忽略该值。只有当用户的geo_enable为true时才有效</param>
        /// <param name="vid">可选参数,即 POI 的 ID，某一个具体的地点，比如天安门</param>
        /// <exception cref="System.ArgumentNullException">status 为NULL</exception>
        /// <exception cref="System.ArgumentOutOfRangeException">Status.Text 超过163个字符</exception>
        /// <returns></returns>
        public Statues Update(Statues status, double lat, double longGeo, string vid)
        {
            if (status == null)
                throw new ArgumentNullException("status", "status 不能为NULL");

            if (status.Text.Length > 163)
                throw new ArgumentOutOfRangeException("status", "微博内容不能超过163个字符");

            var request = requestBase.SetHttpMethod(HttpMethodType.Post).SetUrl(Urls.UpdateStatues).AddParameter(
                new Parameter[] { 
                    new Parameter("status", status.Text), 
                    new Parameter("lat", lat.ToString()), 
                    new Parameter("long", longGeo.ToString()),
                    new Parameter("vid", vid)
                }).CommitRequest();

            var result = request.GetResponse();

            if (result.IsSuccess && result.ResponseText != null)
            {
                return JsonConvert.DeserializeObject<Statues>(result.ResponseText);
            }

            return null;
        }

        /// <summary>
        /// 评论一条微博
        /// </summary>
        /// <param name="id">必选参数，值为被评论微博的ID。如果回复某条评论，则此值为该评论的id。</param>
        /// <param name="status">必选参数，评论内容</param>
        /// <param name="isRetweet">可选参数，是否转发 默认不转发 1为转发</param>
        /// <exception cref="System.ArgumentNullException">status 为NULL</exception>
        /// <exception cref="System.ArgumentOutOfRangeException">Status.Text 超过163个字符</exception>
        /// <returns>微博</returns>
        public Statues Reply(string id, Statues status)
        {
            return Reply(id, status, "0");
        }

        /// <summary>
        /// 评论一条微博
        /// </summary>
        /// <param name="id">必选参数，值为被评论微博的ID。如果回复某条评论，则此值为该评论的id。</param>
        /// <param name="status">必选参数，评论内容</param>
        /// <param name="isRetweet">可选参数，是否转发 默认不转发 1为转发</param>
        /// <exception cref="System.ArgumentNullException">status 为NULL</exception>
        /// <exception cref="System.ArgumentOutOfRangeException">Status.Text 超过163个字符</exception>
        /// <returns></returns>
        public Statues Reply(string id, Statues status, string isRetweet)
        {
            return Reply(id, status, isRetweet, "0");
        }

        /// <summary>
        /// 评论一条微博
        /// </summary>
        /// <param name="id">必选参数，值为被评论微博的ID。如果回复某条评论，则此值为该评论的id。</param>
        /// <param name="status">必选参数，评论内容</param>
        /// <param name="isRetweet">可选参数，是否转发 默认不转发 1为转发</param>
        /// <param name="isCommentToRoot">是否评论给原微博 默认不评论 1为评论</param>
        /// <exception cref="System.ArgumentNullException">status 为NULL</exception>
        /// <exception cref="System.ArgumentOutOfRangeException">Status.Text 超过163个字符</exception>
        /// <returns></returns>
        public Statues Reply(string id, Statues status, string isRetweet, string isCommentToRoot)
        {
            if (status == null)
                throw new ArgumentNullException("status", "status 不能为NULL");

            if (status.Text.Length > 163)
                throw new ArgumentOutOfRangeException("status", "微博内容不能超过163个字符");

            var request = requestBase.SetHttpMethod(HttpMethodType.Post).SetUrl(Urls.Reply).AddParameter(
                new Parameter[] {
                    new Parameter("id", id),
                    new Parameter("status", status.Text),
                    new Parameter("is_retweet", isRetweet),
                    new Parameter("is_comment_to_root", isCommentToRoot)
                }).CommitRequest();

            var result = request.GetResponse();
            if (result.IsSuccess)
            {
                return JsonConvert.DeserializeObject<Statues>(result.ResponseText);
            }
            else
                return null;
        }

        /// <summary>
        /// 转发一条微博
        /// </summary>
        /// <param name="id">必选参数，值为被转发微博的ID</param>
        /// <returns></returns>
        public Statues Retweet(string id)
        {
            return Retweet(id, null);
        }

        /// <summary>
        /// 转发一条微博
        /// </summary>
        /// <param name="id">必选参数，值为被转发微博的ID</param>
        /// <param name="status">可选参数，评论内容，默认为“转发微博。”</param>
        /// <returns></returns>
        public Statues Retweet(string id, Statues status)
        {
            return Retweet(id, status, "0");
        }

        /// <summary>
        /// 转发一条微博
        /// </summary>
        /// <param name="id">必选参数，值为被转发微博的ID</param>
        /// <param name="status">可选参数，评论内容，默认为“转发微博。”</param>
        /// <param name="isComment">可选参数，是否评论 默认不评论 1为评论</param>
        /// <returns>微博</returns>
        public Statues Retweet(string id, Statues status, string isComment)
        {
            return Retweet(id, status, isComment, "0");
        }

        /// <summary>
        /// 转发一条微博
        /// </summary>
        /// <param name="id">必选参数，值为被转发微博的ID</param>
        /// <param name="status">可选参数，评论内容，默认为“转发微博。”</param>
        /// <param name="isComment">可选参数，是否评论 默认不评论 1为评论</param>
        /// <param name="isCommentToRoot">可选参数，是否评论给原微博 默认不评论 1为评论</param>
        /// <returns></returns>
        public Statues Retweet(string id, Statues status, string isComment, string isCommentToRoot)
        {
            var request = requestBase.SetHttpMethod(HttpMethodType.Post).SetUrl(string.Format(Urls.Retweet, id)).AddParameter(
                new Parameter[] {
                    new Parameter("id", id),
                    new Parameter("status", status == null ? "转发微博" : status.Text),
                    new Parameter("is_comment", isComment),
                    new Parameter("is_comment_to_root", isCommentToRoot)
                }).CommitRequest();

            var result = request.GetResponse();
            if (result.IsSuccess)
            {
                return JsonConvert.DeserializeObject<Statues>(result.ResponseText);
            }
            else
                return null;
        }

        /// <summary>
        /// 获取单条微博信息
        /// </summary>
        /// <param name="id">必选参数，值为微博的ID</param>
        /// <returns></returns>
        public Statues Show(string id)
        {
            var request = requestBase.SetHttpMethod(HttpMethodType.Get).SetUrl(string.Format(Urls.Show, id)).AddParameter(
                new Parameter("id", id)).CommitRequest();

            var result = request.GetResponse();
            if (result.IsSuccess && result.ResponseText != null)
            {
                return JsonConvert.DeserializeObject<Statues>(result.ResponseText);
            }
            else
                return null;
        }

        /// <summary>
        /// 查看指定微博的所有评论
        /// </summary>
        /// <param name="id">必选参数，指定的微博id</param>
        /// <returns>指定微博的所有评论</returns>
        public List<Statues> Comments(string id)
        {
            return Comments(id, 30);
        }

        /// <summary>
        /// 查看指定微博的所有评论
        /// </summary>
        /// <param name="id">必选参数，指定的微博id</param>
        /// <param name="count">可选参数，数量，默认为30条，最大为200条</param>
        /// <returns>指定微博的所有评论</returns>
        public List<Statues> Comments(string id, int count)
        {
            return Comments(id, count, true);
        }

        /// <summary>
        /// 查看指定微博的所有评论
        /// </summary>
        /// <param name="id">必选参数，指定的微博id</param>
        /// <param name="count">可选参数，数量，默认为30条，最大为200条</param>
        /// <param name="trimUser">可选参数，值为true时返回的user对象只包含id属性，该参数能在一定程度上减少返回的数据量</param>
        /// <returns>指定微博的所有评论</returns>
        public List<Statues> Comments(string id, int count, bool trimUser)
        {
            return Comments(id, null, null, count, trimUser);
        }

        /// <summary>
        /// 查看指定微博的所有评论
        /// </summary>
        /// <param name="id">必选参数，指定的微博id</param>
        /// <param name="sinceId">可选参数，该参数需传微博id，返回此条索引之后发的微博列表，不包含此条</param>
        /// <param name="maxId">可选参数，该参数需传微博id，返回此条微博之前发的微博列表，包含此条</param>
        /// <param name="count">可选参数，数量，默认为30条，最大为200条</param>
        /// <returns>指定微博的所有评论</returns>
        public List<Statues> Comments(string id, string sinceId, string maxId, int count)
        {
            return Comments(id, sinceId, maxId, count, true);
        }

        /// <summary>
        /// 查看指定微博的所有评论
        /// </summary>
        /// <param name="id">必选参数，指定的微博id</param>
        /// <param name="sinceId">可选参数，该参数需传微博id，返回此条索引之后发的微博列表，不包含此条</param>
        /// <param name="maxId">可选参数，该参数需传微博id，返回此条微博之前发的微博列表，包含此条</param>
        /// <param name="count">可选参数，数量，默认为30条，最大为200条</param>
        /// <param name="trimUser">可选参数，值为true时返回的user对象只包含id属性，该参数能在一定程度上减少返回的数据量</param>
        /// <returns>指定微博的所有评论</returns>
        public List<Statues> Comments(string id, string sinceId, string maxId, int count, bool trimUser)
        {
            var request = requestBase.SetHttpMethod(HttpMethodType.Get).SetUrl(string.Format(Urls.Comments, id)).AddParameter(
                new Parameter("since_id", sinceId),
                new Parameter("max_id", maxId),
                new Parameter("count", count.ToString()),
                new Parameter("trim_user", trimUser ? "true" : "false")).CommitRequest();

            var result = request.GetResponse();

            if (result.IsSuccess)
            {
                return JsonConvert.DeserializeObject<List<Statues>>(result.ResponseText);
            }
            else
                return null;
        }

        /// <summary>
        /// 删除指定的微博，也可以撤销已转发的微博
        /// </summary>
        /// <param name="id">必选参数，值为删除或撤销转发微博的ID</param>
        /// <returns></returns>
        public Statues Destroy(string id)
        {
            var request = requestBase.SetHttpMethod(HttpMethodType.Post).SetUrl(string.Format(Urls.Destroy, id)).CommitRequest();

            var result = request.GetResponse();

            if (result.IsSuccess && result.ResponseText != null)
            {
                return JsonConvert.DeserializeObject<Statues>(result.ResponseText);
            }
            else
                return null;
        }

        /// <summary>
        /// 获取一条微博被转发的用户信息
        /// </summary>
        /// <param name="id">必选参数，值为被转发微博的ID</param>
        /// <returns></returns>
        public List<Statues> GetRetweetedBy(string id)
        {
            return GetRetweetedBy(id, 30);
        }

        /// <summary>
        /// 获取一条微博被转发的用户信息
        /// </summary>
        /// <param name="id">必选参数，值为被转发微博的ID</param>
        /// <param name="count">可选参数，返回的用户数量，默认为100条，最大100条</param>
        /// <returns></returns>
        public List<Statues> GetRetweetedBy(string id, int count)
        {
            var request = requestBase.SetHttpMethod(HttpMethodType.Get).SetUrl(string.Format(Urls.RetweetedBy, id)).AddParameter(
                new Parameter("count", count.ToString())).CommitRequest();

            var result = request.GetResponse();

            if (result.IsSuccess && result.ResponseText != null)
            {
                return JsonConvert.DeserializeObject<List<Statues>>(result.ResponseText);
            }
            else
                return null;
        }

        private string UploadPic(string filePath)
        {
            return UploadPic(filePath, File.ReadAllBytes(filePath));
        }

        private string UploadPic(string fileName, byte[] fileBytes)
        {
            var boundary = Guid.NewGuid().ToString();
            var request = (HttpWebRequest)System.Net.WebRequest.Create(Urls.Upload);

            request.PreAuthenticate = true;
            request.AllowWriteStreamBuffering = true;
            request.Method = "POST";

            string oauthherad = OAuthUtility.GenerateAuthorizationHeader(realm, Urls.Upload, string.Empty, HttpMethodType.Post, this.Consumer, this.AccessToken, realm, new Parameter[] { });

            request.Headers.Add("Authorization", oauthherad);

            var header = string.Format("--{0}", boundary);
            var footer = string.Format("--{0}--", boundary);

            var contents = new StringBuilder();
            request.ContentType = string.Format("multipart/form-data; boundary={0}", boundary);

            contents.AppendLine(header);
            contents.AppendLine("Content-Type: text/plain; charset=US-ASCII");
            contents.AppendLine("Content-Transfer-Encoding: 8bit");
            contents.AppendLine();
            contents.AppendLine(this.Consumer.ConsumerKey);

            contents.AppendLine(header);
            string fileHeader = string.Format("Content-Disposition: form-data; name=\"{0}\"; filename=\"{1}\"", "pic", fileName);
            string fileData = System.Text.Encoding.GetEncoding("iso-8859-1").GetString(fileBytes);

            contents.AppendLine(fileHeader);
            contents.AppendLine("Content-Type: application/octet-stream; charset=UTF-8");
            contents.AppendLine("Content-Transfer-Encoding: binary");
            contents.AppendLine();
            contents.AppendLine(fileData);
            contents.AppendLine(footer);

            byte[] bytes = Encoding.GetEncoding("iso-8859-1").GetBytes(contents.ToString());
            request.ContentLength = bytes.Length;

            var requestStream = request.GetRequestStream();
            try
            {
                requestStream.Write(bytes, 0, bytes.Length);
            }
            catch (Exception ex)
            {
                throw new Exception("上传图片出错。", ex);
            }
            finally
            {
                requestStream.Close();
                requestStream = null;
            }

            StreamReader responseReader = null;
            string responseText = "";
            try
            {
                responseReader = new StreamReader(request.GetResponse().GetResponseStream());
                responseText = responseReader.ReadToEnd();

                // 匿名类
                var uploadImage = new { upload_image_url = "image_address" };
                var image = JsonConvert.DeserializeAnonymousType(responseText, uploadImage);

                return image.upload_image_url;
            }
            catch (Exception ex)
            {
                throw new Exception("上传图片出错。", ex);
            }
            finally
            {
                request.GetResponse().GetResponseStream().Close();
                responseReader.Close();
                responseReader = null;
            }
        }

        /// <summary>
        /// 发布图片微博
        /// </summary>
        /// <param name="fileName">图片路径，必选参数，支持jpg、png、bmp、gif这四种图片格式，上传图片大小在20M以内,此参数不参与Oauth签名。Oauth相关的验证参数请直接放在Header里</param>
        /// <param name="fileBytes">图片，桌面程序为null</param>
        /// <returns></returns>
        public Statues Upload(string fileName, byte[] fileBytes)
        {
            return Upload(fileName, fileBytes, null);
        }

        /// <summary>
        /// 发布图片微博
        /// </summary>
        /// <param name="fileName">图片名字（桌面程序为图片路径），必选参数，支持jpg、png、bmp、gif这四种图片格式，上传图片大小在20M以内,此参数不参与Oauth签名。Oauth相关的验证参数请直接放在Header里</param>
        /// <param name="fileBytes">图片，桌面程序为null</param>
        /// <param name="text">文字内容</param>
        /// <returns></returns>
        public Statues Upload(string fileName, byte[] fileBytes, string text)
        {
            return Upload(fileName, fileBytes, text, 0, 0);
        }

        /// <summary>
        /// 发布图片微博
        /// </summary>
        /// <param name="fileName">图片名字（桌面程序为图片路径），必选参数，支持jpg、png、bmp、gif这四种图片格式，上传图片大小在20M以内,此参数不参与Oauth签名。Oauth相关的验证参数请直接放在Header里</param>
        /// <param name="fileBytes">图片（桌面程序为null）</param>
        /// <param name="text">文字内容</param>
        /// <param name="lat">选参数，即纬度。范围在+90.0 到 -90.0，如果超出这个范围则忽略该值，必须与long参数一起使用，否则忽略该值。只有当用户的geo_enable为true时才有效</param>
        /// <param name="longGeo">可选参数,即经度。范围在+180.0到-180.0，如果超出这个范围则忽略该值，必须与lat参数一起使用，否则忽略该值。只有当用户的geo_enable为true时才有效</param>
        /// <returns></returns>
        public Statues Upload(string fileName, byte[] fileBytes, string text, double lat, double longGeo)
        {
            return Upload(fileName, fileBytes, text, lat, longGeo, null);
        }

        /// <summary>
        /// 发布图片微博
        /// </summary>
        /// <param name="fileName">图片名字（桌面程序为图片路径），必选参数，支持jpg、png、bmp、gif这四种图片格式，上传图片大小在20M以内,此参数不参与Oauth签名。Oauth相关的验证参数请直接放在Header里</param>
        /// <param name="fileBytes">图片，桌面程序为null</param>
        /// <param name="text">文字内容</param>
        /// <param name="lat">选参数，即纬度。范围在+90.0 到 -90.0，如果超出这个范围则忽略该值，必须与long参数一起使用，否则忽略该值。只有当用户的geo_enable为true时才有效</param>
        /// <param name="longGeo">可选参数,即经度。范围在+180.0到-180.0，如果超出这个范围则忽略该值，必须与lat参数一起使用，否则忽略该值。只有当用户的geo_enable为true时才有效</param>
        /// <param name="vid">可选参数,即 POI 的 ID，某一个具体的地点，比如天安门</param>
        /// <returns></returns>
        public Statues Upload(string fileName, byte[] fileBytes, string text, double lat, double longGeo, string vid)
        {
            string imageAddr;
            if (fileBytes == null)
            {
                imageAddr = UploadPic(fileName);
            }
            else
            {
                imageAddr = UploadPic(fileName, fileBytes);
            }

            return Update(new Statues { Text = text + "  " + imageAddr }, lat, longGeo, vid);
        }

        #endregion

        #region 用户

        /// <summary>
        /// 获取指定用户信息
        /// </summary>
        /// <param name="screen_name">用户的个性网址</param>
        /// <returns></returns>
        public Users UserShow(string screen_name)
        {
            return UserShow(screen_name, null);
        }

        /// <summary>
        /// 获取指定用户信息
        /// </summary>
        /// <param name="id">可选参数，用户的个性网址或用户ID</param>
        /// <param name="screen_name">用户的个性网址</param>
        /// <returns></returns>
        public Users UserShow(string screen_name, string id)
        {
            return UserShow(screen_name, id, null);
        }

        /// <summary>
        /// 获取指定用户信息
        /// </summary>
        /// <param name="id">可选参数，用户的个性网址或用户ID</param>
        /// <param name="name">可选参数，用户的昵称</param>
        /// <param name="screen_name">用户的个性网址</param>
        /// <returns></returns>
        public Users UserShow(string screen_name, string id, string name)
        {
            return UserShow(screen_name, id, name, null);
        }

        /// <summary>
        /// 获取指定用户信息
        /// </summary>
        /// <param name="id">可选参数，用户的个性网址或用户ID</param>
        /// <param name="name">可选参数，用户的昵称</param>
        /// <param name="user_id">可选参数，用户ID</param>
        /// <param name="screen_name">用户的个性网址</param>
        /// <returns></returns>
        public Users UserShow(string screen_name, string id, string name, string user_id)
        {
            var request = requestBase.SetHttpMethod(HttpMethodType.Get).SetUrl(Urls.UserShow).AddParameter(
                    new Parameter[] { 
                        new Parameter("id", id),
                        new Parameter("screen_name", screen_name),
                        new Parameter("name", name),
                        new Parameter("user_id", user_id)
                    }).CommitRequest();

            var result = request.GetResponse();

            if (result.IsSuccess && result.ResponseText != null)
            {
                return JsonConvert.DeserializeObject<Users>(result.ResponseText);
            }
            else
                return null;
        }

        /// <summary>
        /// 获取指定用户的关注用户列表
        /// </summary>
        /// <param name="cursor">可选参数，分页参数，单页只能包含30个关注列表</param>
        /// <returns></returns>
        public List<Users> Friends(string screenName)
        {
            return Friends(screenName, null, 1);
        }

        /// <summary>
        /// 获取指定用户的关注用户列表
        /// </summary>
        /// <param name="userId">可选参数. 用户ID，主要是用来区分用户ID跟微博昵称相同产生歧义的情况</param>
        /// <param name="cursor">可选参数，分页参数，单页只能包含30个关注列表</param>
        /// <returns></returns>
        public List<Users> Friends(string userId, int cursor)
        {
            return Friends(null, userId, cursor);
        }

        /// <summary>
        /// 获取指定用户的关注用户列表
        /// </summary>
        /// <param name="userId">可选参数. 用户ID，主要是用来区分用户ID跟微博昵称相同产生歧义的情况</param>
        /// <param name="screenName">可选参数，该用户的个性网址，也可以传user_id</param>
        /// <param name="cursor">可选参数，分页参数，单页只能包含30个关注列表</param>
        /// <returns></returns>
        public List<Users> Friends(string screenName, string userId, int cursor)
        {
            var request = requestBase.SetHttpMethod(HttpMethodType.Get).SetUrl(Urls.Friends).AddParameter(
                new Parameter("user_id", userId),
                new Parameter("screen_name", screenName),
                new Parameter("cursor", cursor.ToString())
                ).CommitRequest();

            var result = request.GetResponse();

            if (result.IsSuccess && result.ResponseText != null)
            {
                var fans = new { next_cursor = "1", users = new List<Users>(), previous_cursor = "-1" };
                return JsonConvert.DeserializeAnonymousType(result.ResponseText, fans).users;
            }
            else
                return null;
        }

        /// <summary>
        /// 获取指定被关注用户列表
        /// </summary>
        /// <param name="screenName">可选参数，该用户的个性网址，也可以传user_id</param>
        /// <returns></returns>
        public List<Users> Followers(string screenName)
        {
            return Followers(null, screenName, 1);
        }

        /// <summary>
        /// 获取指定被关注用户列表
        /// </summary>
        /// <param name="cursor">可选参数，分页参数，单页只能包含30个关注列表</param>
        /// <param name="userId">可选参数. 用户ID，主要是用来区分用户ID跟微博昵称相同产生歧义的情况</param>
        /// <returns></returns>
        public List<Users> Followers(string userId, int cursor)
        {
            return Followers(userId, null, 1);
        }

        /// <summary>
        /// 获取指定被关注用户列表
        /// </summary>
        /// <param name="cursor">可选参数，分页参数，单页只能包含30个关注列表</param>
        /// <param name="userId">可选参数. 用户ID，主要是用来区分用户ID跟微博昵称相同产生歧义的情况</param>
        /// <param name="screenName">可选参数，该用户的个性网址，也可以传user_id</param>
        /// <returns></returns>
        public List<Users> Followers(string userId, string screenName, int cursor)
        {
            var request = requestBase.SetHttpMethod(HttpMethodType.Get).SetUrl(Urls.Followers).AddParameter(
                new Parameter("user_id", userId),
                new Parameter("screen_name", screenName),
                new Parameter("cursor", cursor.ToString())
                ).CommitRequest();

            var result = request.GetResponse();

            if (result.IsSuccess && result.ResponseText != null)
            {
                var fans = new { next_cursor = "1", users = new List<Users>(), previous_cursor = "-1" };
                return JsonConvert.DeserializeAnonymousType(result.ResponseText, fans).users;
            }
            else
                return null;
        }

        /// <summary>
        /// 返回用户可能感兴趣的用户，随机返回指定数目的用户
        /// </summary>
        /// <returns></returns>
        public List<Users> Suggestions()
        {
            return Suggestions(30);
        }

        /// <summary>
        /// 返回用户可能感兴趣的用户，随机返回指定数目的用户
        /// </summary>
        /// <param name="count">可选参数，指定随机返回的用户数目。默认为30个，最多返回30个</param>
        /// <returns></returns>
        public List<Users> Suggestions(int count)
        {
            return Suggestions(count, true);
        }

        /// <summary>
        /// 返回用户可能感兴趣的用户，随机返回指定数目的用户
        /// </summary>
        /// <param name="count">可选参数，指定随机返回的用户数目。默认为30个，最多返回30个</param>
        /// <param name="trimUser">可选参数，值为true时返回最基本的用户数据，使用此参数可以减少返回数据量，默认为false</param>
        /// <returns></returns>
        public List<Users> Suggestions(int count, bool trimUser)
        {
            var request = requestBase.SetHttpMethod(HttpMethodType.Get).SetUrl(Urls.Suggestions).AddParameter(
                new Parameter("count", count.ToString()), new Parameter("trim_user", trimUser ? "true" : "false")).CommitRequest();

            var result = request.GetResponse();

            if (result.IsSuccess && result.ResponseText != null)
            {
                var slst = new { users = new List<Users>() };
                return JsonConvert.DeserializeAnonymousType(result.ResponseText, slst).users;
            }
            else
                return null;
        }

        /// <summary>
        /// 获取推荐的I达人的用户列表
        /// </summary>
        /// <returns></returns>
        public List<Users> SuggestionsIFollowers()
        {
            return SuggestionsIFollowers(null);
        }

        /// <summary>
        /// 获取推荐的I达人的用户列表
        /// </summary>
        /// <param name="cursor">可选参数，分页参数</param>
        /// <returns></returns>
        public List<Users> SuggestionsIFollowers(string cursor)
        {
            return SuggestionsIFollowers(cursor, false);
        }

        /// <summary>
        /// 获取推荐的I达人的用户列表
        /// </summary>
        /// <param name="cursor">可选参数，分页参数</param>
        /// <param name="trimUser">可选参数，值为true时返回最基本的用户数据，使用此参数可以减少返回数据量，默认为false</param>
        /// <returns></returns>
        public List<Users> SuggestionsIFollowers(string cursor, bool trimUser)
        {
            OAuthRequest request = requestBase.SetHttpMethod(HttpMethodType.Get).SetUrl(Urls.SuggestionsIFollowers).AddParameter(
                new Parameter("cursor", cursor),
                new Parameter("trim_user", trimUser ? "true" : "false")).CommitRequest();

            var result = request.GetResponse();

            if (result.IsSuccess && result.ResponseText != null)
            {
                var silst = new { users = new List<Users>() };
                return JsonConvert.DeserializeAnonymousType(result.ResponseText, silst).users;
            }
            else
                return null;
        }

        #endregion

        #region 关注

        /// <summary>
        /// 关注指定用户
        /// </summary>
        /// <param name="screenName">可选参数，该用户的个性网址，也可以传user_id</param>
        /// <returns></returns>
        public Users FriendshipsCreate(string screenName)
        {
            return FriendshipsCreate(null, screenName);
        }

        /// <summary>
        /// 关注指定用户
        /// </summary>
        /// <param name="userId">可选参数. 用户ID，主要是用来区分用户ID跟微博昵称相同产生歧义的情况</param>
        /// <param name="screenName">可选参数，该用户的个性网址，也可以传user_id</param>
        /// <returns></returns>
        public Users FriendshipsCreate(string userId, string screenName)
        {
            var request = requestBase.SetHttpMethod(HttpMethodType.Post).SetUrl(Urls.FriendshipCreate).AddParameter(
                new Parameter("user_id", userId),
                new Parameter("screen_name", screenName)).CommitRequest();

            var result = request.GetResponse();
            if (result.IsSuccess && result.ResponseText != null)
            {
                return JsonConvert.DeserializeObject<Users>(result.ResponseText);
            }
            else
                return null;
        }

        /// <summary>
        /// 获取两个用户的相互关注关系
        /// </summary>
        /// <param name="sourceId">可选参数，指定用户的userId</param>
        /// <param name="sourceScreenName">可选参数，指定用户的个性网址</param>
        /// <returns></returns>
        public Friendship FriendshipsShow(string targetId, string targetScreenName)
        {
            return FriendshipsShow(targetId, targetScreenName, null);
        }

        /// <summary>
        /// 获取两个用户的相互关注关系
        /// </summary>
        /// <param name="sourceId">可选参数，指定用户的userId</param>
        /// <param name="sourceScreenName">可选参数，指定用户的个性网址</param>
        /// <param name="targetId">可选参数，指定用户的userId</param>
        /// <returns></returns>
        public Friendship FriendshipsShow(string targetId, string targetScreenName, string sourceId)
        {
            return FriendshipsShow(targetId, targetScreenName, sourceId, null);
        }

        /// <summary>
        /// 获取两个用户的相互关注关系
        /// </summary>
        /// <param name="sourceId">可选参数，指定用户的userId</param>
        /// <param name="sourceScreenName">可选参数，指定用户的个性网址</param>
        /// <param name="targetId">可选参数，指定用户的userId</param>
        /// <param name="targetScreenName">可选参数，目标用户的个性网址</param>
        /// <returns></returns>
        public Friendship FriendshipsShow(string targetId, string targetScreenName, string sourceId, string sourceScreenName)
        {
            if (string.IsNullOrEmpty(targetId) && string.IsNullOrEmpty(targetScreenName))
            {
                throw new ArgumentException("target_id 和 target_screen_name 不能同时为空。", "targetId/targetScreenName");
            }

            var request = requestBase.SetHttpMethod(HttpMethodType.Get).SetUrl(Urls.FriendshipShow).AddParameter(
                new Parameter[] {
                    new Parameter("source_id", sourceId),
                    new Parameter("source_screen_name", sourceScreenName),
                    new Parameter("target_id", targetId),
                    new Parameter("target_screen_name", targetScreenName)
                }).CommitRequest();

            var result = request.GetResponse();

            if (result.IsSuccess && result.ResponseText != null)
            {
                return JsonConvert.DeserializeObject<Friendship>(result.ResponseText);
            }
            else
                return null;
        }

        /// <summary>
        /// 取消关注指定用户
        /// </summary>
        /// <param name="userId">可选参数. 用户ID，主要是用来区分用户ID跟微博昵称相同产生歧义的情况</param>
        /// <returns></returns>
        public Users FriendshipsDestroy(string screenName)
        {
            return FriendshipsDestroy(null, screenName);
        }

        /// <summary>
        /// 取消关注指定用户
        /// </summary>
        /// <param name="userId">可选参数. 用户ID，主要是用来区分用户ID跟微博昵称相同产生歧义的情况</param>
        /// <param name="screenName">可选参数，该用户的个性网址，也可以传user_id</param>
        /// <returns></returns>
        public Users FriendshipsDestroy(string userId, string screenName)
        {
            var request = requestBase.SetHttpMethod(HttpMethodType.Post).SetUrl(Urls.FriendshipDestroy).AddParameter(
                new Parameter("user_id", userId),
                new Parameter("screen_name", screenName)).CommitRequest();

            var result = request.GetResponse();
            if (result.IsSuccess && result.ResponseText != null)
            {
                return JsonConvert.DeserializeObject<Users>(result.ResponseText);
            }
            else
                return null;
        }

        #endregion

        #region 热榜

        /// <summary>
        /// 获取当前的热门转发榜
        /// </summary>
        /// <returns></returns>
        public List<TopRetweets> TopRetweets()
        {
            return TopRetweets("oneHour");
        }

        /// <summary>
        /// 获取当前的热门转发榜
        /// </summary>
        /// <param name="size">可选参数，返回数量,不传则为默认值(当前为50),最多50</param>
        /// <returns></returns>
        public List<TopRetweets> TopRetweets(int size)
        {
            return TopRetweets("oneHour", size);
        }

        /// <summary>
        /// 获取当前的热门转发榜
        /// </summary>
        /// <param name="type">必选参数，排行榜类型,当前有4种:oneHour,sixHours,oneDay,oneWeek</param>
        /// <returns></returns>
        public List<TopRetweets> TopRetweets(string type)
        {
            return TopRetweets(type, 50);
        }

        /// <summary>
        /// 获取当前的热门转发榜
        /// </summary>
        /// <param name="type">必选参数，排行榜类型,当前有4种:oneHour,sixHours,oneDay,oneWeek</param>
        /// <param name="size">可选参数，返回数量,不传则为默认值(当前为50),最多50</param>
        /// <returns></returns>
        public List<TopRetweets> TopRetweets(string type, int size)
        {
            var request = requestBase.SetHttpMethod(HttpMethodType.Get).SetUrl(Urls.TopRetweets).AddParameter(
                new Parameter("type", type),
                new Parameter("size", size.ToString())).CommitRequest();

            var result = request.GetResponse();

            if (result.IsSuccess && result.ResponseText != null)
            {
                return JsonConvert.DeserializeObject<List<TopRetweets>>(result.ResponseText);
            }
            else
                return null;
        }

        #endregion

        #region 话题

        /// <summary>
        /// 推荐话题API，其效果与“我的首页”右侧的推荐话题一致
        /// </summary>
        /// <returns></returns>
        public List<Trend> TrendsRecommended()
        {
            var request = requestBase.SetHttpMethod(HttpMethodType.Get).SetUrl(Urls.TrendsRecommended).CommitRequest();

            var result = request.GetResponse();

            if (result.IsSuccess)
            {
                var Trends = new { trends = new List<Trend>() };

                return JsonConvert.DeserializeAnonymousType(result.ResponseText, Trends).trends;
            }
            else
                return null;
        }

        #endregion

        #region 私信

        /// <summary>
        /// 获取当前用户私信列表
        /// </summary>
        /// <returns></returns>
        public List<DirectMessage> DirectMessages()
        {
            return DirectMessages(null);
        }

        /// <summary>
        /// 获取当前用户私信列表
        /// </summary>
        /// <param name="sinceId">可选参数，上一页最后一条私信的id</param>
        /// <returns></returns>
        public List<DirectMessage> DirectMessages(string sinceId)
        {
            return DirectMessages(sinceId, 30);
        }

        /// <summary>
        /// 获取当前用户私信列表
        /// </summary>
        /// <param name="sinceId">可选参数，上一页最后一条私信的id</param>
        /// <param name="count">可选参数，获取私信的数量</param>
        /// <returns></returns>
        public List<DirectMessage> DirectMessages(string sinceId, int count)
        {
            var request = requestBase.SetHttpMethod(HttpMethodType.Get).SetUrl(Urls.DirectMessages).AddParameter(
                new Parameter("count", count.ToString()), new Parameter("since_id", sinceId)).CommitRequest();

            var result = request.GetResponse();

            if (result.IsSuccess && result.ResponseText != null)
            {
                return JsonConvert.DeserializeObject<List<DirectMessage>>(result.ResponseText);
            }
            else
                return null;
        }

        /// <summary>
        /// 获取当前用户发送的私信列表
        /// </summary>
        /// <returns></returns>
        public List<DirectMessage> DirectMessageSent()
        {
            return DirectMessageSent(null);
        }

        /// <summary>
        /// 获取当前用户发送的私信列表
        /// </summary>
        /// <param name="sinceId">可选参数，上一页最后一条私信的id</param>
        /// <returns></returns>
        public List<DirectMessage> DirectMessageSent(string sinceId)
        {
            return DirectMessageSent(sinceId, 30);
        }

        /// <summary>
        /// 获取当前用户发送的私信列表
        /// </summary>
        /// <param name="sinceId">可选参数，上一页最后一条私信的id</param>
        /// <param name="count">可选参数，获取私信的数量</param>
        /// <returns></returns>
        public List<DirectMessage> DirectMessageSent(string sinceId, int count)
        {
            var request = requestBase.SetHttpMethod(HttpMethodType.Get).SetUrl(Urls.DirectMessagesSent).AddParameter(
                new Parameter("count", count.ToString()), new Parameter("since_id", sinceId)).CommitRequest();

            var result = request.GetResponse();

            if (result.IsSuccess && result.ResponseText != null)
            {
                return JsonConvert.DeserializeObject<List<DirectMessage>>(result.ResponseText);
            }
            else
                return null;
        }

        /// <summary>
        /// 发送一条私信
        /// </summary>
        /// <param name="userName">必选参数，收信用户的昵称，即name</param>
        /// <param name="text">必选参数，私信内容</param>
        /// <returns></returns>
        public DirectMessage DirectMessageNew(string userName, string text)
        {
            var request = requestBase.SetHttpMethod(HttpMethodType.Post).SetUrl(Urls.DirectMessagesNew).AddParameter(
                new Parameter("user", userName),
                new Parameter("text", text)).CommitRequest();

            var result = request.GetResponse();

            if (result.IsSuccess && result.ResponseText != null)
            {
                return JsonConvert.DeserializeObject<DirectMessage>(result.ResponseText);
            }
            else
                return null;
        }

        /// <summary>
        /// 删除一条私信
        /// </summary>
        /// <param name="id">必选参数，删除的私信id</param>
        /// <returns></returns>
        public DirectMessage DirectMessageDestory(string id)
        {
            var request = requestBase.SetHttpMethod(HttpMethodType.Post).SetUrl(string.Format(Urls.DirectMessageDestroy, id)).CommitRequest();
            var result = request.GetResponse();

            if (result.IsSuccess && result.ResponseText != null)
            {
                return JsonConvert.DeserializeObject<DirectMessage>(result.ResponseText);
            }
            else
                return null;
        }

        #endregion

        #region 帐号

        /// <summary>
        /// 网易通行证开通微博，当用户有通行证账号且未开通微博时，可以通过此API开通
        /// </summary>
        /// <param name="url">地址</param>
        /// <param name="idNum">可选参数，身份证号，如身份证号不合法，则返回400</param>
        /// <param name="mobile">可选参数，手机号，如手机号不合法，则返回400</param>
        /// <param name="nikeName">可选参数，昵称，如果昵称不合法，则返回400</param>
        /// <param name="realName">可选参数，真实姓名，如真实姓名不合法，则返回400</param>
        /// <returns></returns>
        public string Activate(string url, string nikeName, string realName, string mobile, string idNum)
        {
            var request = requestBase.SetHttpMethod(HttpMethodType.Post).SetUrl(Urls.Activate).AddParameter(
                new Parameter("nick_name", nikeName),
                new Parameter("real_name", realName),
                new Parameter("mobile", mobile),
                new Parameter("id_num", idNum)
                ).CommitRequest();

            var result = request.GetResponse();

            if (result.IsSuccess && !string.IsNullOrEmpty(result.ResponseText))
            {
                var r = new { id = "id", error = "", parameter = "", request = "" };

                var rt = JsonConvert.DeserializeAnonymousType(result.ResponseText, r);

                if (result.StatusCode == HttpStatusCode.OK)
                    return rt.id;
                else
                    return rt.error;
            }
            else
                return null;
        }

        /// <summary>
        /// 修改用户个人资料
        /// 本API只对高级第三方合作者开放，申请此API权限请发邮件到OpenAPI@yeah.net，未授权访问则返回403
        /// </summary>
        /// <param name="url">地址</param>
        /// <param name="nikeName">可选参数，昵称，如果昵称不合法，则返回400</param>
        /// <param name="realName">可选参数，真实姓名，如真实姓名不合法，则返回400</param>
        /// <param name="description">可选参数，用户描述，如超过163个字符，则返回400</param>
        /// <param name="province">可选参数，用户省份，如省份不合法，则返回400</param>
        /// <param name="city">可选参数，用户城市，如城市不合法，则返回400</param>
        /// <returns></returns>
        public Users UpdateProfile(string url, string nikeName, string realName, string description, string province, string city)
        {
            var request = requestBase.SetHttpMethod(HttpMethodType.Post).SetUrl(Urls.UpdateProfile).AddParameter(
                new Parameter("nick_name", nikeName),
                new Parameter("real_name", realName),
                new Parameter("description", description),
                new Parameter("province", province),
                new Parameter("city", city)).CommitRequest();

            var result = request.GetResponse();

            if (result.IsSuccess && !string.IsNullOrEmpty(result.ResponseText))
                return JsonConvert.DeserializeObject<Users>(result.ResponseText);
            else
                return null;
        }

        /// <summary>
        /// 修改用户个人头像
        /// 本API只对高级第三方合作者开放，申请此API权限请发邮件到OpenAPI@yeah.net，未授权访问则返回403
        /// </summary>
        /// <param name="url">地址</param>
        /// <param name="image">必选参数，图片地址。支持jpg、png、gif这三种图片格式，上传图片大小在4M以内</param>
        /// <returns></returns>
        public Users UpdateProfileImage(string image)
        {
            string imgUrl = UploadPic(image);
            var request = requestBase.SetHttpMethod(HttpMethodType.Post).SetUrl(Urls.UpdateProfielImage).AddParameter(
                new Parameter("", imgUrl)
                ).CommitRequest();

            var result = request.GetResponse();

            if (result.IsSuccess && !string.IsNullOrEmpty(result.ResponseText))
                return JsonConvert.DeserializeObject<Users>(result.ResponseText);
            else
                return null;
        }

        /// <summary>
        /// 返回当前小时内剩余访问次数
        /// </summary>
        /// <param name="url">地址</param>
        /// <returns></returns>
        public string RateLimitStatus()
        {
            var request = requestBase.SetHttpMethod(HttpMethodType.Get).SetUrl(Urls.RateLimitStatus).CommitRequest();
            var result = request.GetResponse();

            if (result.IsSuccess && result.ResponseText != null)
            {
                return result.ResponseText;
            }
            else
                return string.Empty;
        }

        #endregion

        #region 收藏

        /// <summary>
        /// 获取指定用户的收藏
        /// </summary>
        /// <param name="id">必选参数，可以为该用户的个性网址(screen_name)</param>
        /// <returns></returns>
        public List<Statues> Favorites(string id)
        {
            return Favorites(id, null, 30);
        }

        /// <summary>
        /// 获取指定用户的收藏
        /// </summary>
        /// <param name="id">必选参数，可以为该用户的个性网址(screen_name)</param>
        /// <param name="count">返回微博数量，默认30，最大200</param>
        /// <returns></returns>
        public List<Statues> Favorites(string id, int count)
        {
            return Favorites(id, null, 30);
        }

        /// <summary>
        /// 获取指定用户的收藏
        /// </summary>
        /// <param name="id">必选参数，可以为该用户的个性网址(screen_name)</param>
        /// <param name="count">返回微博数量，默认30，最大200</param>
        /// <param name="sinceId">分页参数，传微博ID,返回此条微博以前发的微博列表,不包含此条</param>
        /// <returns></returns>
        public List<Statues> Favorites(string id, string sinceId, int count)
        {
            var request = requestBase.SetHttpMethod(HttpMethodType.Get).SetUrl(string.Format(Urls.Favorites, id)).AddParameter(
                new Parameter("count", count.ToString()),
                new Parameter("since_id", sinceId)).CommitRequest();

            var result = request.GetResponse();
            if (result.IsSuccess && result.ResponseText != null)
            {
                return JsonConvert.DeserializeObject<List<Statues>>(result.ResponseText);
            }
            else
                return null;
        }

        /// <summary>
        /// 添加收藏
        /// </summary>
        /// <param name="id">必选参数，要收藏的微博ID</param>
        /// <returns></returns>
        public Statues FavoritesCreate(string id)
        {
            var request = requestBase.SetHttpMethod(HttpMethodType.Post).SetUrl(string.Format(Urls.FavoritesCreate, id)).CommitRequest();
            var result = request.GetResponse();

            if (result.IsSuccess && result.ResponseText != null)
            {
                return JsonConvert.DeserializeObject<Statues>(result.ResponseText);
            }
            else
                return null;
        }

        /// <summary>
        /// 删除当前用户的收藏
        /// </summary>
        /// <param name="id">必选参数，要删除的微博ID</param>
        /// <returns></returns>
        public Statues FavoritesDestroy(string id)
        {
            var request = requestBase.SetHttpMethod(HttpMethodType.Post).SetUrl(string.Format(Urls.FavoritesDestroy, id)).CommitRequest();
            var result = request.GetResponse();

            if (result.IsSuccess && result.ResponseText != null)
            {
                return JsonConvert.DeserializeObject<Statues>(result.ResponseText);
            }
            else
                return null;
        }

        #endregion

        #region 黑名单

        /// <summary>
        /// 阻止指定用户
        /// </summary>
        /// <param name="userId">可选参数. 用户ID，主要是用来区分用户ID跟微博昵称相同产生歧义的情况</param>
        /// <param name="screenName">可选参数，该用户的个性网址，也可以传user_id</param>
        /// <returns></returns>
        public Users BlocksCreate(string userId, string screenName)
        {
            var request = requestBase.SetHttpMethod(HttpMethodType.Post).SetUrl(Urls.BlocksCreate).AddParameter(
                new Parameter("user_id", userId),
                new Parameter("screen_name", screenName)).CommitRequest();

            var result = request.GetResponse();
            if (result.IsSuccess && result.ResponseText != null)
            {
                return JsonConvert.DeserializeObject<Users>(result.ResponseText);
            }
            else
                return null;
        }

        /// <summary>
        /// 取消已阻止的用户，即将该用户移除黑名单
        /// </summary>
        /// <param name="userId">可选参数. 用户ID，主要是用来区分用户ID跟微博昵称相同产生歧义的情况</param>
        /// <param name="screenName">可选参数，该用户的个性网址，也可以传user_id</param>
        /// <returns></returns>
        public Users BlocksDestroy(string userId, string screenName)
        {
            var request = requestBase.SetHttpMethod(HttpMethodType.Post).SetUrl(Urls.BlocksDestroy).AddParameter(
                new Parameter("user_id", userId),
                new Parameter("screen_name", screenName)).CommitRequest();

            var result = request.GetResponse();
            if (result.IsSuccess && result.ResponseText != null)
            {
                return JsonConvert.DeserializeObject<Users>(result.ResponseText);
            }
            else
                return null;
        }

        /// <summary>
        /// 判断是否已经阻止用户,如已阻止此用户则返回用户信息，如未阻止则返回状态404，同时提示“此用户未被加入黑名单”
        /// </summary>
        /// <param name="userId">可选参数. 用户ID，主要是用来区分用户ID跟微博昵称相同产生歧义的情况</param>
        /// <param name="screenName">可选参数，该用户的个性网址，也可以传user_id</param>
        /// <returns></returns>
        public Users BlocksExits(string userId, string screenName)
        {
            var request = requestBase.SetHttpMethod(HttpMethodType.Post).SetUrl(Urls.BlocksExists).AddParameter(
                new Parameter("user_id", userId),
                new Parameter("screen_name", screenName)).CommitRequest();

            var result = request.GetResponse();
            if (result.IsSuccess && result.ResponseText != null)
            {
                return JsonConvert.DeserializeObject<Users>(result.ResponseText);
            }
            else
                return null;
        }

        /// <summary>
        /// 返回当前登录用户屏蔽的用户列表
        /// </summary>
        /// <returns></returns>
        public List<Users> Blocking()
        {
            var request = requestBase.SetHttpMethod(HttpMethodType.Get).SetUrl(Urls.BlocksBlocking).CommitRequest();
            var result = request.GetResponse();

            if (result.IsSuccess)
            {
                return JsonConvert.DeserializeObject<List<Users>>(result.ResponseText);
            }
            else
                return null;
        }

        /// <summary>
        /// 已阻止的Id列表
        /// </summary>
        /// <exception cref="System.NotImplementedException">该方法未实现</exception>
        /// <returns></returns>
        public List<string> BlockingIds()
        {
            // todo: 已阻止Id 列表
            throw new NotImplementedException();
        }

        #endregion

        #region 地址位置相关

        /// <summary>
        /// 返回指定位置附近或者符合搜索关键字的地点列表
        /// </summary>
        /// <param name="lat">可选参数，即纬度。范围在+90.0 到 -90.0，如果超出这个范围则忽略该值，必须与long参数一起使用，否则忽略该值</param>
        /// <param name="longGeo">可选参数,即经度。范围在+180.0到-180.0，如果超出这个范围则忽略该值，必须与lat参数一起使用，否则忽略该值</param>
        /// <param name="q">可选参数，搜索关键字，必须与经纬度（lat,long）参数同时使用才有效，,根据定位的数据在用户所在的城市搜索相应的POI，如没有经纬度参数或无结果返回404</param>
        /// <returns></returns>
        public List<Venue> GetVenues(double lat, double longGeo, string q)
        {
            return GetVenues(lat, longGeo, q, 30);
        }

        /// <summary>
        /// 返回指定位置附近或者符合搜索关键字的地点列表
        /// </summary>
        /// <param name="lat">可选参数，即纬度。范围在+90.0 到 -90.0，如果超出这个范围则忽略该值，必须与long参数一起使用，否则忽略该值</param>
        /// <param name="longGeo">可选参数,即经度。范围在+180.0到-180.0，如果超出这个范围则忽略该值，必须与lat参数一起使用，否则忽略该值</param>
        /// <param name="count">可选参数，返回数据的个数，默认为10，最大为50</param>
        /// <param name="q">可选参数，搜索关键字，必须与经纬度（lat,long）参数同时使用才有效，,根据定位的数据在用户所在的城市搜索相应的POI，如没有经纬度参数或无结果返回404</param>
        /// <returns></returns>
        public List<Venue> GetVenues(double lat, double longGeo, string q, int count)
        {
            var request = requestBase.SetHttpMethod(HttpMethodType.Get).SetUrl(Urls.Venues).AddParameter(
                new Parameter[] {
                    new Parameter("lat", lat.ToString()),
                    new Parameter("long", longGeo.ToString()),
                    new Parameter("count", count.ToString()),
                    new Parameter("q", q)
                }).CommitRequest();

            var result = request.GetResponse();
            if (result.IsSuccess && result.ResponseText != null)
            {
                var Venues = new { venues = new List<Venue>() };

                return JsonConvert.DeserializeAnonymousType(result.ResponseText, Venues).venues;
            }
            else
                return null;
        }

        /// <summary>
        /// 通过经纬度或POI返回与地理位置相关的微博列表，如传经纬度则返回附近的微博列表，传POI的ID则返回此POI下的微博列表
        /// </summary>
        /// <param name="vid">可选参数,即POI的id，单独使用时值返回包含此vid的微博。如果经纬度也同时传入，则将两种微博（包含vid或经纬度的）一起返回，按照发微博的时间倒序排列。如果根据vid找不到相应的poi且无定位参数时则返回404</param>
        /// <returns></returns>
        public List<Statues> LocationTimeLine(string vid)
        {
            return LocationTimeLine(0, 0, vid);
        }

        /// <summary>
        /// 通过经纬度或POI返回与地理位置相关的微博列表，如传经纬度则返回附近的微博列表，传POI的ID则返回此POI下的微博列表
        /// </summary>
        /// <param name="lat">可选参数，即纬度。范围在+90.0 到 -90.0，如果超出这个范围则忽略该值，必须与long参数一起使用，否则忽略该值</param>
        /// <param name="longGeo">可选参数,即经度。范围在+180.0到-180.0，如果超出这个范围则忽略该值，必须与lat参数一起使用，否则忽略该值</param>
        /// <returns></returns>
        public List<Statues> LocationTimeLine(double lat, double longGeo)
        {
            return LocationTimeLine(lat, longGeo, null);
        }

        /// <summary>
        /// 通过经纬度或POI返回与地理位置相关的微博列表，如传经纬度则返回附近的微博列表，传POI的ID则返回此POI下的微博列表
        /// </summary>
        /// <param name="lat">可选参数，即纬度。范围在+90.0 到 -90.0，如果超出这个范围则忽略该值，必须与long参数一起使用，否则忽略该值</param>
        /// <param name="longGeo">可选参数,即经度。范围在+180.0到-180.0，如果超出这个范围则忽略该值，必须与lat参数一起使用，否则忽略该值</param>
        /// <param name="vid">可选参数,即POI的id，单独使用时值返回包含此vid的微博。如果经纬度也同时传入，则将两种微博（包含vid或经纬度的）一起返回，按照发微博的时间倒序排列。如果根据vid找不到相应的poi且无定位参数时则返回404</param>
        /// <returns></returns>
        public List<Statues> LocationTimeLine(double lat, double longGeo, string vid)
        {
            return LocationTimeLine(lat, longGeo, vid, null);
        }

        /// <summary>
        /// 通过经纬度或POI返回与地理位置相关的微博列表，如传经纬度则返回附近的微博列表，传POI的ID则返回此POI下的微博列表
        /// </summary>
        /// <param name="lat">可选参数，即纬度。范围在+90.0 到 -90.0，如果超出这个范围则忽略该值，必须与long参数一起使用，否则忽略该值</param>
        /// <param name="longGeo">可选参数,即经度。范围在+180.0到-180.0，如果超出这个范围则忽略该值，必须与lat参数一起使用，否则忽略该值</param>
        /// <param name="vid">可选参数,即POI的id，单独使用时值返回包含此vid的微博。如果经纬度也同时传入，则将两种微博（包含vid或经纬度的）一起返回，按照发微博的时间倒序排列。如果根据vid找不到相应的poi且无定位参数时则返回404</param>
        /// <param name="sinceId">可选参数，该参数需传cursor_id,返回此条索引之前发的微博列表,不包含此条</param>
        /// <returns></returns>
        public List<Statues> LocationTimeLine(double lat, double longGeo, string vid, string sinceId)
        {
            return LocationTimeLine(lat, longGeo, vid, sinceId, null);
        }

        /// <summary>
        /// 通过经纬度或POI返回与地理位置相关的微博列表，如传经纬度则返回附近的微博列表，传POI的ID则返回此POI下的微博列表
        /// </summary>
        /// <param name="lat">可选参数，即纬度。范围在+90.0 到 -90.0，如果超出这个范围则忽略该值，必须与long参数一起使用，否则忽略该值</param>
        /// <param name="longGeo">可选参数,即经度。范围在+180.0到-180.0，如果超出这个范围则忽略该值，必须与lat参数一起使用，否则忽略该值</param>
        /// <param name="vid">可选参数,即POI的id，单独使用时值返回包含此vid的微博。如果经纬度也同时传入，则将两种微博（包含vid或经纬度的）一起返回，按照发微博的时间倒序排列。如果根据vid找不到相应的poi且无定位参数时则返回404</param>
        /// <param name="sinceId">可选参数，该参数需传cursor_id,返回此条索引之前发的微博列表,不包含此条</param>
        /// <param name="maxId">可选参数，该参数需传cursor_id,返回此条索引之后发的微博列表，包含此条</param>
        /// <returns></returns>
        public List<Statues> LocationTimeLine(double lat, double longGeo, string vid, string sinceId, string maxId)
        {
            return LocationTimeLine(lat, longGeo, vid, sinceId, maxId, 30);
        }

        /// <summary>
        /// 通过经纬度或POI返回与地理位置相关的微博列表，如传经纬度则返回附近的微博列表，传POI的ID则返回此POI下的微博列表
        /// </summary>
        /// <param name="lat">可选参数，即纬度。范围在+90.0 到 -90.0，如果超出这个范围则忽略该值，必须与long参数一起使用，否则忽略该值</param>
        /// <param name="longGeo">可选参数,即经度。范围在+180.0到-180.0，如果超出这个范围则忽略该值，必须与lat参数一起使用，否则忽略该值</param>
        /// <param name="vid">可选参数,即POI的id，单独使用时值返回包含此vid的微博。如果经纬度也同时传入，则将两种微博（包含vid或经纬度的）一起返回，按照发微博的时间倒序排列。如果根据vid找不到相应的poi且无定位参数时则返回404</param>
        /// <param name="sinceId">可选参数，该参数需传cursor_id,返回此条索引之前发的微博列表,不包含此条</param>
        /// <param name="maxId">可选参数，该参数需传cursor_id,返回此条索引之后发的微博列表，包含此条</param>
        /// <param name="count">可选参数，返回微博的个数，默认为30，最大为200</param>
        /// <returns></returns>
        public List<Statues> LocationTimeLine(double lat, double longGeo, string vid, string sinceId, string maxId, int count)
        {
            var request = requestBase.SetHttpMethod(HttpMethodType.Get).SetUrl(Urls.LocationTimeLine).AddParameter(
                new Parameter[]{
                    new Parameter("lat", lat.ToString()),
                    new Parameter("long", longGeo.ToString()),
                    new Parameter("vid", vid),
                    new Parameter("count", count.ToString()),
                    new Parameter("since_id", sinceId),
                    new Parameter("max_id", maxId)
                }).CommitRequest();
            var result = request.GetResponse();

            if (result.IsSuccess && result.ResponseText != null)
            {
                return JsonConvert.DeserializeObject<List<Statues>>(result.ResponseText);
            }
            else
                return null;
        }

        #endregion

        #region 搜索

        /// <summary>
        /// 搜索
        /// </summary>
        /// <param name="q">必选参数，关键字,最大长度25,如果以#起始的关键字会作为tag搜索精确匹配</param>
        /// <param name="page">可选参数，当前页数，默认为第一页</param>
        /// <param name="perPage">可选参数，返回数量,最大20</param>
        /// <returns></returns>
        public string Search(string q, int page, int perPage)
        {
            var request = requestBase.SetHttpMethod(HttpMethodType.Get).SetUrl(Urls.Search).AddParameter(
                new Parameter[] {
                    new Parameter("q", q),
                    new Parameter("page", page.ToString()),
                    new Parameter("per_page", perPage.ToString())
                }).CommitRequest();

            var result = request.GetResponse();
            if (result.IsSuccess)
            {
                return result.ResponseText;
            }
            else
                return null;
        }

        /// <summary>
        /// 搜索微博
        /// </summary>
        /// <param name="q">必选参数，关键字,最大长度25,如果以#起始的关键字会作为tag搜索精确匹配</param>
        /// <returns></returns>
        public List<Statues> SearchStatus(string q)
        {
            return SearchStatus(q, 1);
        }

        /// <summary>
        /// 搜索微博
        /// </summary>
        /// <param name="q">必选参数，关键字,最大长度25,如果以#起始的关键字会作为tag搜索精确匹配</param>
        /// <param name="page">可选参数，当前页数，默认为第一页</param>
        /// <returns></returns>
        public List<Statues> SearchStatus(string q, int page)
        {
            return SearchStatus(q, page, 20);
        }

        /// <summary>
        /// 搜索微博
        /// </summary>
        /// <param name="q">必选参数，关键字,最大长度25,如果以#起始的关键字会作为tag搜索精确匹配</param>
        /// <param name="page">可选参数，当前页数，默认为第一页</param>
        /// <param name="perPage">可选参数，返回数量,最大20</param>
        /// <returns></returns>
        public List<Statues> SearchStatus(string q, int page, int perPage)
        {
            return SearchStatus(q, page, perPage, true);
        }

        /// <summary>
        /// 搜索微博
        /// </summary>
        /// <param name="q">必选参数，关键字,最大长度25,如果以#起始的关键字会作为tag搜索精确匹配</param>
        /// <param name="page">可选参数，当前页数，默认为第一页</param>
        /// <param name="perPage">可选参数，返回数量,最大20</param>
        /// <param name="trimUse">可选参数，值为true时返回的user对象只包含id属性，该属性能在一定程度上减少返回的数据量</param>
        /// <returns></returns>
        public List<Statues> SearchStatus(string q, int page, int perPage, bool trimUse)
        {
            var request = requestBase.SetHttpMethod(HttpMethodType.Get).SetUrl(Urls.StatuesSearch).AddParameter(
                new Parameter[] {
                    new Parameter("q", q),
                    new Parameter("page", page.ToString()),
                    new Parameter("per_page", perPage.ToString()),
                    new Parameter("trim_user", trimUse ? "true" : "false")
                }).CommitRequest();

            var result = request.GetResponse();
            if (result.IsSuccess && result.ResponseText != null)
            {
                return JsonConvert.DeserializeObject<List<Statues>>(result.ResponseText);
            }
            else
                return null;
        }

        /// <summary>
        /// 搜索用户
        /// </summary>
        /// <param name="q">必选参数，关键字,最大长度25</param>
        /// <returns></returns>
        public List<Users> SearchUser(string q)
        {
            return SearchUser(q, 1);
        }

        /// <summary>
        /// 搜索用户
        /// </summary>
        /// <param name="q">必选参数，关键字,最大长度25</param>
        /// <param name="page">可选参数，当前页数，默认为第一页</param>
        /// <returns></returns>
        public List<Users> SearchUser(string q, int page)
        {
            return SearchUser(q, page, 20);
        }

        /// <summary>
        /// 搜索用户
        /// </summary>
        /// <param name="q">必选参数，关键字,最大长度25</param>
        /// <param name="page">可选参数，当前页数，默认为第一页</param>
        /// <param name="perPage">可选参数，返回数量,最大20</param>
        /// <returns></returns>
        public List<Users> SearchUser(string q, int page, int perPage)
        {
            var request = requestBase.SetHttpMethod(HttpMethodType.Get).SetUrl(Urls.UserSearch).AddParameter(
                new Parameter[] {
                    new Parameter("q", q),
                    new Parameter("page", page.ToString()),
                    new Parameter("per_page", perPage.ToString())
                }).CommitRequest();

            var result = request.GetResponse();
            if (result.IsSuccess && result.ResponseText != null)
            {
                return JsonConvert.DeserializeObject<List<Users>>(result.ResponseText);
            }
            else
                return null;
        }

        #endregion

        /// <summary>
        /// 通用方法
        /// </summary>
        /// <param name="url">地址</param>
        /// <param name="type">类型</param>
        /// <param name="parameters">参数</param>
        /// <returns></returns>
        /// <remarks>上面的方法都可以通过这个方法完成</remarks>
        public string CommonTask(string url, HttpMethodType type, params Parameter[] parameters)
        {
            var request = requestBase.SetHttpMethod(type).SetUrl(url).AddParameter(parameters).CommitRequest();

            var result = request.GetResponse();

            if (result.IsSuccess)
                return result.ResponseText;
            else
                return null;

        }

#endif

    }
}
